home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************/
- /* code copyright 1995-1996 Andrew Johnson - ALL RIGHTS RESERVED*/
- /* ajohnson@eecs.uic.edu */
- /* */
- /* Electronic Visualization Lab (M/C 154) */
- /* University of Illinois at Chicago */
- /* 851 South Morgan St. Room 1120 SEO */
- /* Chicago, IL 60607-7053 */
- /* */
- /* (312) 996-3002 (312) 413-7585 FAX */
- /***********************************************************************/
- /* battalion.c v 1.4 */
- /* main routines for battalion */
- /***********************************************************************/
- /* */
- /* code within '#ifdef SOLARIS' by Johan Hagman */
- /* */
- /**************************************************/
-
- #include "battalion.h"
-
- #ifdef MACVERSION
-
- #define ROADFILE "DATA:road.data"
- #define TREEFILE "DATA:tree.data"
- #define TANKFILE "DATA:tank.data"
-
- #include "tkmacglobals.h"
-
- void setPlayerName(char *);
- drawGrow(void);
-
- #else
-
- #ifndef AMIGAVERSION
- #define DATADIR "./battalion.data"
- #else
- #define DATADIR "battalion.data"
- #endif
- #define ROADFILE "DATA/road.data"
- #define TREEFILE "DATA/tree.data"
- #define TANKFILE "DATA/tank.data"
-
- #endif
-
-
- /*****************/
- /* network stuff */
- /*****************/
-
- int buildingBoomSoFarCounter;
- int buildingBoomSoFar[800];
-
- int buildingBoomThisFrameCounter;
- int buildingBoomThisFrame[20];
- int currentTankNumber;
-
-
- /*********/
- /* times */
- /*********/
-
- time_t beg, now;
- time_t timePaused, time3d, timeSound, timeMusic, timeDetail;
-
- /**************/
- /* indicators */
- /**************/
-
- int frames;
-
- int moreThanOne;
-
- int viewW, viewH;
-
- int alone;
- int oldview, view;
- int showOptions;
- int paused;
- int noSound;
- int no3D;
- int mode3D;
- int mode;
- int backdrop;
- int itsChristmas;
- int mapHeight;
- int lod;
-
- /* it would be nice to dynamically get these ... */
- int XMAXSCREEN = 1280;
-
- #ifdef SOLARIS
- int YMAXSCREEN = 1024;
- #else
- int YMAXSCREEN = 1040;
- #endif
-
- /************/
- /* counters */
- /************/
-
- int killtanks, killmtanks, killhelos;
- int killCHHs, killmechags, killheros,
- killfighters, killplanes, killlaunchers;
-
- int mainCounter;
- int totalCounter;
- int firingDelay;
- int arrivalTime;
- int showframes; /* also used to filter out repetitive sounds */
- float accuracy;
-
- int treeID;
-
- /****************/
- /* window stuff */
- /****************/
-
- long windowOriginX, windowOriginY, windowSizeX, windowSizeY;
- long monitorType;
- long windowWide, windowTall, windowLeft, windowTop;
- GLuint viewL, viewR;
- long zmax;
- int doBigClear;
-
- float lastTankY, lastTankTheta, lastTankRad;
-
- int pointerGrab;
-
- /*********/
- /* lists */
- /*********/
-
- struct road * roadSystem;
- struct projectile * projectFlight;
- struct boom * projectboom;
- struct tank * tanklist;
- struct tank * slaglist;
- struct tree * treelist;
-
- /*********/
- /* files */
- /*********/
-
- char dataPath[MAXPATH];
- char fullPath[MAXPATH];
- char scorefullPath[MAXPATH];
-
- /*****************/
- /* monster stuff */
- /*****************/
-
- struct monsterInfo Googelon;
- float offsetX; /* needed global to bank flutter */
- struct targetInfo * targets;
-
-
- /*********************/
- /* battlefield stuff */
- /*********************/
-
- float globalxshift, globalzshift;
-
- GLfloat xrot, xsaverot, yrot, ysaverot;
-
- struct tree allTreesOnPlane[MAXTREESONPLANE];
- struct tree * allTreesOnPlanePtrs[MAXTREESONPLANE];
-
- /* needed for the targets to blow up trees off the player's plane */
- int numTreesEverywhere;
- struct tree allTreesEverywhere[MAXTREESONPLANE];
- struct tree * allTreesEverywherePtrs[MAXTREESONPLANE];
-
- int numTreesOnPlane;
-
- struct fireType fires[MAXFIRESONPLANE];
- int flameCount;
-
- struct tank * allTanks2OnPlane[MAXTANKSONPLANE];
- struct tank allTanksOnPlane[MAXTANKSONPLANE];
- int numTanksOnPlane;
-
- int frameCount;
- int outFrameCount;
- time_t frameTime;
-
- GLuint monsterLookat;
- GLuint overviewLookat;
-
- int Gfor, Gbak, Gturn;
-
- float textLineWidth;
-
- struct timeval startTime, endTime;
-
- /*
- #ifdef MACVERSION
-
- double macStart, macEnd;
-
- #endif
- */
-
- char playerName[16];
- char playerHome[256];
-
- struct score G[3];
- struct score F[3];
- struct score V[3];
- struct score T[3];
- int multipleHighScores;
-
- struct projectile * tproj, *deadproj;
- struct boom * tboom, *deadboom;
-
- void * arena;
- void * sharedmem;
-
- int sizeBoom;
- int sizeTank;
- int sizeProjectile;
-
- int netUp;
- int client;
-
- int biggestTankNumberSent;
-
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void goToHighDetail()
- {
- glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
- glEnable(GL_DEPTH_TEST);
- }
-
- void goToLowDetail()
- {
- glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
- glDisable(GL_DEPTH_TEST);
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void updateScores(char * scorefullPath, int monster, int monsterScore, int mode, char * playerName)
- {
- char thaName[MAXSTRING];
- FILE * hiScoreFile;
- char garbage;
- struct score * currentOne;
- int c;
- int position;
- int current;
-
- if (mode == DEMOMODE)
- strcpy(thaName, "demo");
- else
- strcpy(thaName, playerName);
-
- hiScoreFile = fopen(scorefullPath, "r");
-
- if (hiScoreFile != NULL)
- {
- for(c=0;c<3;c++)
- fscanf(hiScoreFile, "%d%c%s", &(G[c].number), &garbage, G[c].name);
- for(c=0;c<3;c++)
- fscanf(hiScoreFile, "%d%c%s", &(V[c].number), &garbage, V[c].name);
- for(c=0;c<3;c++)
- fscanf(hiScoreFile, "%d%c%s", &(F[c].number), &garbage, F[c].name);
- for(c=0;c<3;c++)
- fscanf(hiScoreFile, "%d%c%s", &(T[c].number), &garbage, T[c].name);
-
- fclose(hiScoreFile);
-
- switch (monster){
- case GOOGELON: currentOne = G;
- break;
-
- case TECHS: currentOne = T;
- break;
-
- case VAPOUR: currentOne = V;
- break;
-
- case FLUTTER: currentOne = F;
- break;
- }
-
- /* where does the new score belong */
- /***********************************/
-
- if (monsterScore > currentOne[0].number)
- position = 0;
-
- else if (monsterScore > currentOne[1].number)
- position = 1;
-
- else if (monsterScore > currentOne[2].number)
- position = 2;
-
-
- if (multipleHighScores)
- {
- switch (position) {
- case 0: currentOne[2].number = currentOne[1].number;
- strcpy(currentOne[2].name, currentOne[1].name);
-
- currentOne[1].number = currentOne[0].number;
- strcpy(currentOne[1].name, currentOne[0].name);
-
- currentOne[0].number = monsterScore;
- strcpy(currentOne[0].name, thaName);
- break;
-
- case 1: currentOne[2].number = currentOne[1].number;
- strcpy(currentOne[2].name, currentOne[1].name);
-
- currentOne[1].number = monsterScore;
- strcpy(currentOne[1].name, thaName);
- break;
-
- case 2: currentOne[2].number = monsterScore;
- strcpy(currentOne[2].name, thaName);
- break;
- }
- }
- else
- {
- /* does the player currently have a score for this monster */
- /***********************************************************/
-
- current = -1;
-
- if (same(thaName, currentOne[0].name))
- current = 0;
- else if(same(thaName, currentOne[1].name))
- current = 1;
- else if (same(thaName, currentOne[2].name))
- current = 2;
-
- switch (position) {
- case 0: switch (current)
- {
- case 0: currentOne[0].number = monsterScore;
- strcpy(currentOne[0].name, thaName);
- break;
-
- case 1: currentOne[1].number = currentOne[0].number;
- strcpy(currentOne[1].name, currentOne[0].name);
-
- currentOne[0].number = monsterScore;
- strcpy(currentOne[0].name, thaName);
- break;
-
- case -1:
- case 2: currentOne[2].number = currentOne[1].number;
- strcpy(currentOne[2].name, currentOne[1].name);
-
- currentOne[1].number = currentOne[0].number;
- strcpy(currentOne[1].name, currentOne[0].name);
-
- currentOne[0].number = monsterScore;
- strcpy(currentOne[0].name, thaName);
- break;
- }
-
-
- break;
-
- case 1: switch (current)
- {
- case 0: break;
-
- case 1: currentOne[1].number = monsterScore;
- strcpy(currentOne[1].name, thaName);
- break;
-
- case -1:
- case 2: currentOne[2].number = currentOne[1].number;
- strcpy(currentOne[2].name, currentOne[1].name);
-
- currentOne[1].number = monsterScore;
- strcpy(currentOne[1].name, thaName);
- break;
- }
-
-
- break;
-
- case 2: switch (current)
- {
- case 0: break;
-
- case 1: break;
-
- case -1:
- case 2: currentOne[2].number = monsterScore;
- strcpy(currentOne[2].name, thaName);
- break;
- }
-
- break;
- }
- }
-
- hiScoreFile = fopen(scorefullPath, "w");
-
- for(c=0;c<3;c++)
- fprintf(hiScoreFile, "%d%c%s\n", G[c].number, ' ', G[c].name);
- for(c=0;c<3;c++)
- fprintf(hiScoreFile, "%d%c%s\n", V[c].number, ' ', V[c].name);
- for(c=0;c<3;c++)
- fprintf(hiScoreFile, "%d%c%s\n", F[c].number, ' ', F[c].name);
- for(c=0;c<3;c++)
- fprintf(hiScoreFile, "%d%c%s\n", T[c].number, ' ', T[c].name);
-
- fclose(hiScoreFile);
- }
- }
-
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void quickTanks()
- {
- struct tank *temptank;
-
- /**********************************************************/
- /* copy all vehicles everywhere into quick-access array */
- /**********************************************************/
-
- numTanksOnPlane = 0;
- for(temptank = tanklist->next;(temptank != NULL);temptank = temptank->next)
- {
- allTanks2OnPlane[numTanksOnPlane] = temptank;
- allTanksOnPlane[numTanksOnPlane] = *temptank;
- numTanksOnPlane += 1;
- if (numTanksOnPlane >= MAXTANKSONPLANE)
- {
- showError("Too many tanks on plane");
- numTanksOnPlane -= 1;
- }
- }
-
- for(temptank = slaglist->next;(temptank != NULL);temptank = temptank->next)
- {
- allTanks2OnPlane[numTanksOnPlane] = temptank;
- allTanksOnPlane[numTanksOnPlane] = *temptank;
- numTanksOnPlane += 1;
- if (numTanksOnPlane >= MAXTANKSONPLANE)
- {
- showError("Too Many Tanks on Plane");
- numTanksOnPlane -= 1;
- }
- }
-
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* determine whether a vehicle is blocked */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- int checkForBlock(struct tank * ttank, float rad, float theta, float y)
- {
- register int tankCounter;
-
- struct tank* ttank2;
- struct tree * temptree;
- struct targetInfo * temptarget;
- float tankInRad, tankOutRad;
- float treeInRad, treeOutRad;
- float raddy;
- float angle;
- float targx, targz;
- float rad2;
- float angDiff;
- int useTarg;
- int blocked;
-
- tankInRad = rad + 0.2;
- tankOutRad = rad - 0.8;
- treeInRad = rad + 0.3;
- treeOutRad = rad - 1.2;
-
-
- blocked = 0;
-
- /**********************************************/
- /* is the vehicle blocked by another vehicle? */
- /**********************************************/
-
- tankCounter = 0;
- while ((tankCounter < numTanksOnPlane) && (!blocked))
- {
- ttank2 = allTanks2OnPlane[tankCounter];
- rad2 = ttank2->rad;
-
- if ((ttank->goforit == ttank2->goforit) &&
- (tankInRad >= rad2) && /* check radius */
- (tankOutRad <= rad2) &&
- (ttank2 != ttank) && /* not same tank */
- (fabs(theta - ttank2->theta) < 0.22) && /* check angle */
- (fabs(ttank2->y - y) <= 0.6) /* check altitude */
- )
- blocked = 1;
-
- tankCounter += 1;
- }
-
- /**********************************************************/
- /* is the vehicle blocked by a structure (tree,building)? */
- /**********************************************************/
-
- useTarg = 0;
- for(temptarget = targets->next; temptarget != NULL; temptarget = temptarget->next)
- if (&(temptarget->monster) == ttank->goforit)
- {
- targx = temptarget->x;
- targz = temptarget->z;
- useTarg = 1;
- }
-
- for(temptree = treelist->next;(temptree != NULL) && (!blocked); temptree = temptree->next)
- {
- if (useTarg) /* radius to the target */
- {
- raddy = sqrt((temptree->x - targx) * (temptree->x - targx) + (temptree->z - targz) * (temptree->z - targz));
- }
- else
- {
- raddy = temptree->rad; /* radius and theta to the player's monster */
- }
-
- if ((treeInRad >= raddy) && (treeOutRad <= raddy) && (y <= (temptree->height + 0.5)))
- {
- if (useTarg) /* theta to the target */
- {
- angle = computeAngle(temptree->z, targz, temptree->x, targx);
- }
- else
- {
- angle = temptree->theta;
- }
-
- if (angle < 0)
- angle += TWOPI;
- else if (angle >= TWOPI)
- angle -= TWOPI;
-
- if (theta < 0)
- theta += TWOPI;
- else if (theta >= TWOPI)
- theta -= TWOPI;
-
- angDiff = theta - angle;
-
- if ((fabs(angDiff) < 0.31) || (fabs(angDiff + TWOPI) < 0.31) ||
- (fabs(angDiff - TWOPI) < 0.31))
- blocked = 1;
- }
- }
-
- return (blocked);
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* increase monster's score based on kill */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void addScore(int tank, struct monsterInfo * m)
- {
- switch(tank){
- case TANK: killtanks += 1;
- if (m!= NULL)
- m->monsterScore += 5;
- break;
-
- case LAUNCHER: killlaunchers += 1;
- if (m!= NULL)
- m->monsterScore += 10;
- break;
-
- case MASERTANK: killmtanks += 1;
- if (m!= NULL)
- m->monsterScore += 15;
- break;
-
- case HELO: killhelos += 1;
- if (m!= NULL)
- m->monsterScore += 8;
- break;
-
- case MECHAG: killmechags += 1;
- break;
-
- case CHH: killCHHs += 1;
- break;
-
- case HERO: killheros += 1;
- break;
-
- case AIRPLANE: killplanes += 1;
- if (m!= NULL)
- m->monsterScore += 25;
- break;
-
- case FIGHTER: killfighters += 1;
- if (m!= NULL)
- m->monsterScore += 20;
- break;
-
- case BUILDING: if (m!= NULL)
- m->monsterScore += 50;
- break;
-
- case PARTIALM: if (m!= NULL)
- m->monsterScore += 4;
- break;
-
- case PARTIALH: if (m!= NULL)
- m->monsterScore += 5;
- break;
-
- case PARTIALC: if (m!= NULL)
- m->monsterScore += 3;
- break;
-
- case MONSTER: if (m!= NULL)
- m->monsterScore += 1;
- break;
-
- default: showError("Bogus Score! (addScore)");
- break;
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* add a new explosion */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void addBoom(float x, float y, float z, struct monsterInfo* m)
- {
- struct boom * tempboom2;
- struct boom tempboom;
-
- tempboom2 = (struct boom *) amalloc(sizeBoom, arena);
-
- if (tempboom2 != NULL)
- {
- tempboom.mine = m;
- tempboom.count = 1;
- tempboom.x = x;
-
- if (y >= PLANEY)
- tempboom.y = y;
- else
- tempboom.y = PLANEY;
-
- tempboom.z = z;
- tempboom.next = projectboom->next;
- *tempboom2 = tempboom;
- projectboom->next = tempboom2;
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* add a new projectile */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void addProjectile( float x, float y, float z, int type,
- float xv, float yv, float zv, float accuracy, struct monsterInfo * m)
- {
- struct projectile * temp;
- struct projectile tempProj;
-
-
- switch(type){
- case PROJTANK: doSound(TANKFIRE);
- break;
-
- case PROJROCKET: doSound(HELOROCKET);
- break;
-
- case PROJTECHS:
- case PROJHERO: doSound(TECHSHOOT);
- break;
-
- }
-
- temp = (struct projectile *) amalloc(sizeProjectile, arena);
-
- if (temp != NULL)
- {
- tempProj.count = 0;
-
- tempProj.mine = m;
-
- tempProj.x = x;
- tempProj.y = y;
- tempProj.z = z;
-
- tempProj.type = (char) type;
-
- tempProj.xv = xv;
- tempProj.yv = yv;
- tempProj.zv = zv;
-
- if (accuracy != 0)
- {
- tempProj.xv += randy(5.0)/accuracy;
- tempProj.yv += randy(5.0)/accuracy;
- tempProj.zv += randy(5.0)/accuracy;
- }
-
-
- tempProj.next = projectFlight->next;
- *temp = tempProj;
- projectFlight->next = temp;
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* update all projectiles on the battlefield */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void updateProjectiles()
- {
- float px, py, pz;
- float qx, qy, qz;
- float floor, ceiling;
- int i, dead;
- int inPlay, monsterHit, groundHit;
- struct targetInfo * temptarget;
- struct monsterInfo thaMonster;
- float monsterX, monsterZ;
-
- struct projectile * pproj, *killer, *temp;
-
- int tankCounter, treeCounter;
- float maxX, maxZ, minX, minZ;
-
- maxX = maxZ = minX = minZ = 0;
-
- /******************************************************************************/
- /* figure out the range of valid shells bounded by all monsters + PLANESIZE */
- /******************************************************************************/
-
- for(temptarget = targets->next; temptarget != NULL; temptarget = temptarget->next)
- {
- if (temptarget->x > maxX)
- maxX = temptarget->x;
- if (temptarget->x < minX)
- minX = temptarget->x;
- if (temptarget->z > maxZ)
- maxZ = temptarget->z;
- if (temptarget->z < minZ)
- minZ = temptarget->z;
- }
-
- maxX += (PLANESIZE+1);
- maxZ += (PLANESIZE+1);
- minX -= (PLANESIZE+1);
- minZ -= (PLANESIZE+1);
-
- /**********************************/
- /* process each shell in turn */
- /**********************************/
-
- floor = PLANEY + 0.1;
- ceiling = PLANEY + 10;
-
- flameCount = 0;
-
- temp = projectFlight;
- while (temp->next != NULL)
- {
- dead = 0;
-
- pproj = temp->next;
-
- pproj->count += 1;
-
- if (pproj->count > ARMCOUNT)
- pproj->count = ARMCOUNT;
-
- /**********************************/
- /* is projectile still in play? */
- /**********************************/
-
- px = fabs(pproj->x);
- py = pproj->y;
- pz = fabs(pproj->z);
-
- qx = pproj->x;
- qy = pproj->y;
- qz = pproj->z;
-
- monsterHit = 0;
-
- /**************************************************/
- /* did the projectile hit the player's monster? */
- /**************************************************/
-
- if ((pproj->type != PROJWATER) && (pproj->type != PROJFIRE) && (pproj->type != PROJSCAR))
- {
- if ((Googelon.monsterIsDead != 1) &&
- (px <= Googelon.width) && (pz <= Googelon.width) &&
- (py <= Googelon.height) && (py >= Googelon.bottom))
- {
- if ((pproj->type != PROJTECHS) || ((pproj->type == PROJTECHS) && (pproj->mine != &Googelon)))
- {
- Googelon.energyRemaining -= BLASTPOINTS;
- monsterHit = 1;
-
- /*
- if (pproj->mine != NULL)
- pproj->mine->monsterScore += 1;
- */
- }
- }
-
- /********************************************/
- /* did the projectile hit another target? */
- /********************************************/
-
- for(temptarget = targets->next;temptarget != NULL;temptarget = temptarget->next)
- {
- thaMonster = temptarget->monster;
- monsterX = temptarget->x;
- monsterZ = temptarget->z;
-
- if ( (thaMonster.monsterIsDead != 1) &&
- (qx <= (monsterX+thaMonster.width)) && (qz <= (monsterZ+thaMonster.width)) &&
- (qx >= (monsterX-thaMonster.width)) && (qz >= (monsterZ-thaMonster.width)) &&
- (qy <= thaMonster.height) && (qy >= thaMonster.bottom))
- {
- if ((pproj->type != PROJTECHS) || ((pproj->type == PROJTECHS) && (pproj->mine != &(temptarget->monster))))
- {
- temptarget->monster.energyRemaining -= BLASTPOINTS;
- monsterHit = 1;
-
- /*
- if (pproj->mine != NULL)
- pproj->mine->monsterScore += 1;
- */
- }
- }
- }
- }
-
- if (!monsterHit && (py > floor) && (py < ceiling) &&
- (px > minX) && (pz > minZ) && (px < maxX) && (pz < maxZ))
- inPlay = 1;
- else
- inPlay = 0;
-
- if ((px <= PLANESIZE) && (pz <= PLANESIZE) && (py <= floor) &&
- (pproj->type != PROJWATER) && (pproj->type != PROJSCAR))
- groundHit = 1;
- else
- groundHit = 0;
-
- if (monsterHit || groundHit)
- addBoom(pproj->x, pproj->y, pproj->z, pproj->mine);
-
-
- if (!inPlay)
- dead = 1;
-
- if (inPlay)
- {
- /**********************************/
- /* update projectile position */
- /**********************************/
-
- px = pproj->x += pproj->xv;
- py = pproj->y += pproj->yv;
- pz = pproj->z += pproj->zv;
-
- if (pproj->y < PLANEY)
- py = pproj->y = PLANEY;
-
- /*****************************/
- /* update all the flames */
- /*****************************/
-
- if (pproj->type == PROJFIRE)
- {
- for (i=0;i<2;i++)
- {
- fires[flameCount].x = pproj->x + randy(0.15);
- fires[flameCount].z = pproj->z + randy(0.15);
- if (lod == 0) {
- fires[flameCount].xwid = 0.07 + randy(0.06);
- fires[flameCount].zwid = 0.07 + randy(0.06);
- fires[flameCount].height = 0.15 + randy(0.15);
- } else {
- fires[flameCount].xwid = 0.1 + randy(0.07);
- fires[flameCount].zwid = 0.1 + randy(0.07);
- fires[flameCount].height = 0.2 + randy(0.15);
- }
- do
- fires[flameCount].col = 0.9 + randy(0.25);
- while (fires[flameCount].col > 1);
-
- flameCount += 1;
- if (flameCount >= MAXFIRESONPLANE)
- {
- showError("Too many fires on plane");
- flameCount -= 1;
- }
- }
- }
-
- /**********************************/
- /* shells affected by gravity */
- /**********************************/
-
- if ((pproj->type == PROJTANK) || (pproj->type == PROJWATER))
- pproj->yv -= GRAVITY;
-
- /**********************************/
- /* check for a tank hit */
- /**********************************/
-
- if ((pproj->type != PROJSCAR) && (pproj->type != PROJWATER)
- && ((pproj->count >= ARMCOUNT) || (pproj->type == PROJTECHS) || (pproj->type == PROJFIRE)))
- {
- tankCounter = 0;
- while (tankCounter < numTanksOnPlane)
- {
- if (tankHit(&(allTanksOnPlane[tankCounter]), px, py, pz))
- {
- addBoom(px, py, pz, pproj->mine);
- dead = 1;
- }
- tankCounter += 1;
- }
- }
-
- /**********************************/
- /* check for a tree hit */
- /**********************************/
-
- if ((pproj->type != PROJSCAR) && (pproj->type != PROJWATER))
- {
- treeCounter = 0;
-
- while (treeCounter < numTreesEverywhere)
- {
- if ((fabs(allTreesEverywhere[treeCounter].x - px) < TREEBLASTR) &&
- (fabs(allTreesEverywhere[treeCounter].z - pz) < TREEBLASTR) &&
- (fabs(allTreesEverywhere[treeCounter].y + allTreesEverywhere[treeCounter].height - py) < TREEBLASTHEIGHTR)
- )
- {
- addBoom(px, py, pz, pproj->mine);
- dead = 1;
-
- if ((pproj->type == PROJTECHS) || (pproj->type == PROJFIRE) || (pproj->type == PROJHERO))
- {
- if (allTreesEverywherePtrs[treeCounter]->intact && (allTreesEverywherePtrs[treeCounter]->type == 1))
- addScore(BUILDING, pproj->mine);
-
- allTreesEverywherePtrs[treeCounter]->intact = 0;
- }
-
- if (((pproj->type == PROJTANK) || (pproj->type == PROJROCKET)) && (allTreesEverywhere[treeCounter].type == 0))
- allTreesEverywherePtrs[treeCounter]->intact = 0;
-
- }
- treeCounter += 1;
- }
- }
- }
-
- /************************************/
- /* if projectile is dead, remove it */
- /************************************/
-
- if (dead)
- {
- killer = temp->next;
- temp->next = temp->next->next;
- afree(killer, arena);
- }
- else
- temp = temp->next;
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* update the state of all the structures */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void updatetrees(struct tree * allTrees, int itsChristmas)
- {
- struct tree *temptree, *ttree;
- float x, y, z;
- float Vplane;
- int i, j, k, jmax, l;
- int dead;
-
- buildingBoomThisFrameCounter = 0;
-
- Vplane = sqrt(GRAVITY * 1.5) * 0.7071;
-
- ttree = allTrees;
-
- while (ttree->next != NULL)
- {
- dead = 0;
- temptree = ttree->next;
-
- x = temptree->x;
- y = temptree->y;
- z = temptree->z;
-
- temptree->rad = sqrt(x * x + z * z);
-
- temptree->theta = computeAngle(z, 0, x, 0);
-
-
- /*****************************/
- /* update special structures */
- /*****************************/
-
- if (temptree->type == 1)
- {
- /***********************/
- /* hero beam-in effect */
- /***********************/
-
- if (temptree->treeshape == 33)
- {
- temptree->deathCount += 1;
- if (temptree->deathCount >= 20)
- temptree->intact = 0;
- }
-
- /************/
- /* fountain */
- /************/
-
- if ((temptree->treeshape == 29) && (temptree->intact) && (!itsChristmas))
- {
- addProjectile(x, PLANEY+0.6, z, PROJWATER,
- 2*randy(0.005), .05, 2*randy(0.005), 0, NULL);
- }
-
- /****************/
- /* power towers */
- /****************/
-
- if ((temptree->treeshape == 3) && !(temptree->intact))
- {
- temptree->deathCount += 1;
-
- if (temptree->death2 == -1)
- {
- doSound(CRASH);
-
- buildingBoomThisFrame[buildingBoomThisFrameCounter++] = temptree->number;
- buildingBoomSoFar[buildingBoomSoFarCounter++] = temptree->number;
-
- temptree->death2 = rand() % 360;
- temptree->height = -0.4;
- }
-
- if (temptree->deathCount > 40)
- temptree->deathCount = 40;
- }
- }
-
- /**********************************************/
- /* buildings / trees disappearing / exploding */
- /**********************************************/
-
- if (!(temptree->intact) && (((temptree->type == 1) && (temptree->treeshape != 3)) || (temptree->type == 0)))
- {
- doSound(CRASH);
- dead = 1;
-
- buildingBoomThisFrame[buildingBoomThisFrameCounter++] = temptree->number;
- buildingBoomSoFar[buildingBoomSoFarCounter++] = temptree->number;
-
- switch(temptree->treeshape)
- {
- case 1:
- case 11:
- case 14:
- case 22:
- case 23:
- case 24: jmax = 5;
- break;
- case 33: jmax = 0;
- break;
- default: jmax = 3;
- break;
- }
-
-
- /**********************/
- /* structures explode */
- /**********************/
-
- if (temptree->type == 1)
- {
- for (i=-1; i<2; i++)
- for (j=0; j<jmax; j++)
- for (k=-1; k<2; k++)
- if ((rand() % 100) < 50)
- {
- addProjectile( x + i * 0.2, y + (j * 0.2) + 0.1, z + k * 0.2, PROJTANK,
- sin(randy(PI)) * Vplane, Vplane, cos(randy(PI)) * Vplane, 75, NULL);
- }
-
- if (temptree->treeshape == 9) /* add water into water tower */
- {
- for(l=0;l<30;l++)
- addProjectile(x, PLANEY+1, z, PROJWATER,
- 2*randy(0.02), randy(0.05), 2*randy(0.02), 0, NULL);
- }
- }
-
-
- addProjectile( x - 0.2, PLANEY + 0.14, z + 0.2, PROJFIRE, 0, -0.0005, 0, 10000, NULL);
- addProjectile( x + 0.2, PLANEY + 0.14, z + 0.2, PROJFIRE, 0, -0.0005, 0, 10000, NULL);
- addProjectile( x , PLANEY + 0.14, z - 0.2, PROJFIRE, 0, -0.0005, 0, 10000, NULL);
- }
-
- if (dead)
- {
- ttree->next = temptree->next;
- afree(temptree, arena);
- }
- else
- ttree = ttree->next;
- }
- }
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* update all of the vehicles */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void updateTanks(struct tank * allTanks, float width, float height,
- float bottom, int dead, int monster,
- struct tank* slag, float accuracy, int firingDelay,
- int mainCounter, struct monsterInfo * m, struct targetInfo * targets)
- {
- float xv, yv, zv;
- float Vplane, angle;
- int blocked, maserOn;
- struct tank *killertank, *ttank, *temptank;
- float energyLoss;
- float tankx, tankz;
- int tanktype;
-
- float rad;
- float radToNearestTarget;
- struct targetInfo * nearestTarget;
-
- int aircraft;
- struct targetInfo * temptarget;
- struct monsterInfo * nearestMonster;
-
- float centerX, centerZ;
- float nearAngle;
-
-
- int targetCounter, targetc;
- float targetxs[MAXTARGETS+1];
- float targetzs[MAXTARGETS+1];
- struct targetInfo * targetinfs[MAXTARGETS+1];
-
- /****************************************/
- /* move targets into quick access array */
- /****************************************/
-
- targetCounter = 0;
- for(temptarget = targets->next;temptarget != NULL;temptarget = temptarget->next)
- {
- targetxs[targetCounter] = temptarget->x;
- targetzs[targetCounter] = temptarget->z;
- targetinfs[targetCounter] = temptarget;
- targetCounter++;
- }
-
- centerX = 0;
- centerZ = 0;
-
- maserOn = 0;
- energyLoss = 0;
-
- temptank = allTanks;
-
- while(temptank->next != NULL)
- {
- ttank = temptank->next;
- ttank->count -= 1;
-
- tankx = ttank->x;
- tankz = ttank->z;
- tanktype = ttank->type;
-
- radToNearestTarget = 10000;
- nearestTarget = NULL;
-
- /************************************************/
- /* need to compute radius to the nearest target */
- /************************************************/
-
- for(targetc = 0; targetc < targetCounter; targetc++)
- {
- rad = sqrt((tankx-targetxs[targetc]) * (tankx-targetxs[targetc]) + (tankz-targetzs[targetc]) * (tankz-targetzs[targetc]));
- if (rad < radToNearestTarget)
- {
- radToNearestTarget = rad;
- nearestTarget = targetinfs[targetc];
- nearestMonster = &(nearestTarget->monster);
- centerX = nearestTarget->x;
- centerZ = nearestTarget->z;
- }
- }
-
- /**********************************************/
- /* need to compute radius to player's monster */
- /**********************************************/
-
- rad = sqrt(tankx * tankx + tankz * tankz);
-
- if (rad < radToNearestTarget)
- {
- radToNearestTarget = rad;
- nearestTarget = NULL;
- nearestMonster = m;
- centerX = 0;
- centerZ = 0;
- }
-
-
- ttank->rad = radToNearestTarget;
- ttank->goforit = nearestMonster;
-
-
- if (tanktype == MECHAG) /* mechaG shoots 5X as fast*/
- ttank->count -= 4;
-
- if (tanktype == CHH) /* 009CHH shoots 2X as fast*/
- ttank->count -= 1;
-
-
-
- if (ttank->z == 0)
- ttank->z = NEARZERO;
-
- angle = computeAngle(tankz, centerZ, tankx, centerX);
-
- /**************************/
- /* deal with the aircraft */
- /**************************/
-
- if ((tanktype == AIRPLANE) || (tanktype == FIGHTER))
- aircraft = 1;
- else
- aircraft = 0;
-
- if ((!aircraft) || (aircraft && (ttank->rad > (PLANESIZE*2.5))))
- {
- nearAngle = angle;
- if (fabs(ttank->theta - (angle + TWOPI)) < fabs(ttank->theta - nearAngle))
- nearAngle = angle + TWOPI;
- if (fabs(ttank->theta - (angle - TWOPI)) < fabs(ttank->theta - nearAngle))
- nearAngle = angle - TWOPI;
-
- ttank->theta = 0.8 * ttank->theta + 0.2 * nearAngle;
-
- if (ttank->theta < 0)
- ttank->theta += TWOPI;
- else if (ttank->theta >= TWOPI)
- ttank->theta -= TWOPI;
- }
-
-
- if (aircraft && (ttank->rad > (PLANESIZE*2.5)))
- ttank->count = 0;
-
-
- if ((tanktype == MASERTANK) || (tanktype == CHH) || (tanktype == MECHAG))
- {
- ttank->rand1 = randy(0.025);
- ttank->rand2 = randy(0.025);
- ttank->rand3 = randy(0.025);
- }
-
- /**********************************/
- /* move vehicle */
- /**********************************/
-
- if ((ttank->rad > ttank->finalR) || (tanktype == AIRPLANE) || (tanktype == FIGHTER))
- {
-
- /**********************************/
- /* check for obstacles */
- /**********************************/
-
- if ((tanktype == AIRPLANE) || (tanktype == FIGHTER))
- blocked = 0;
- else
- blocked = checkForBlock(ttank, ttank->rad, ttank->theta, ttank->y);
-
- if (!blocked)
- {
- Vplane = ttank->speed;
-
- ttank->walking += 1;
-
- ttank->zv = cos(ttank->theta) * Vplane;
- ttank->xv = sin(ttank->theta) * Vplane;
-
- ttank->x += ttank->xv;
- ttank->z += ttank->zv;
- }
- }
-
- if ((!dead) && (nearestMonster->monsterIsDead != 1) && (ttank->rad <= ttank->range) && (ttank->rad >= ttank->minrange))
- {
- /**********************************/
- /* mechaGoogelon firing */
- /**********************************/
-
- if ((tanktype == MECHAG))
- {
- if ((ttank->count <= 0) && ((rand() % 5) == 0) && (nearestMonster->monsterIsDead != 1))
- {
- xv = - (ttank->x-centerX) / 12;
- yv = ((height - bottom) * 0.5 + bottom - ttank->y) / 12;
- zv = - (ttank->z-centerZ) / 12;
-
- addProjectile( ttank->x, ttank->y, ttank->z, PROJROCKET,
- xv, yv, zv, accuracy*0.33, NULL);
-
- ttank->count = firingDelay;
- }
-
- if ((ttank->count <= 0) && (ttank->maserCount <= 0) && ((rand() % 10) == 0))
- {
- ttank->maserCount = 10 + (rand() % 5);
- ttank->count = firingDelay;
- }
- if ((ttank->maserCount > 0) && (ttank->rad <= ttank->range))
- {
- maserOn = 1;
- ttank->maserCount -= 1;
-
- nearestMonster->energyRemaining -= 0.5;
- }
- }
-
- /**********************************/
- /* 009 CHH firing */
- /**********************************/
-
- if ((tanktype == CHH))
- {
- if ((ttank->count <= 0) && ((rand() % 5) == 0))
- {
- xv = - (ttank->x-centerX) / 12;
- yv = ((height - bottom) * 0.5 + bottom - ttank->y) / 12;
- zv = - (ttank->z-centerZ) / 12;
-
- addProjectile( ttank->x, ttank->y, ttank->z, PROJROCKET,
- xv, yv, zv, accuracy*0.5, NULL);
-
- ttank->count = firingDelay;
- }
-
- if ((ttank->count <= 0) && (ttank->maserCount <= 0) && ((rand() % 10) == 0))
- {
- ttank->maserCount = 10 + (rand() % 5);
- ttank->count = firingDelay;
- }
- if ((ttank->maserCount > 0) && (ttank->rad <= ttank->range))
- {
- maserOn = 1;
- ttank->maserCount -= 1;
-
- nearestMonster->energyRemaining -= 0.5;
- }
- }
-
- /**********************************/
- /* tank firing shell */
- /**********************************/
-
- if ((tanktype == TANK) && (ttank->count <= 0) && ((rand() % 5) == 0))
- {
- ttank->count = firingDelay;
-
- if (monster == FLUTTER)
- Vplane = sqrt(GRAVITY * ttank->rad) * 0.8071;
- else
- Vplane = sqrt(GRAVITY * ttank->rad) * 0.7071;
-
- xv = sin(ttank->theta) * Vplane;
- zv = cos(ttank->theta) * Vplane;
-
- addProjectile( ttank->x, ttank->y + 0.15, ttank->z, PROJTANK,
- xv, Vplane, zv, accuracy, NULL);
- }
-
- /************************************/
- /* airplane 'dropping' bomb */
- /************************************/
-
- if ((tanktype == AIRPLANE) && (mainCounter % 2))
- {
- addProjectile(ttank->x, ttank->y-0.1, ttank->z, PROJTANK, 0, 0, 0, 0, NULL);
- }
-
- /************************************/
- /* fighter launchine missile */
- /************************************/
-
- if ((tanktype == FIGHTER) && (ttank->count <= 0))
- {
- ttank->count = 1000; /* way bug number */
-
- xv = - (ttank->x-centerX) / 15;
- yv = ((height - bottom) * 0.5 + bottom - ttank->y) / 15;
- zv = - (ttank->z-centerZ) / 15;
-
- addProjectile(ttank->x, ttank->y-0.1, ttank->z, PROJROCKET, xv, yv, zv, accuracy * 0.75, NULL);
- addProjectile(ttank->x, ttank->y-0.1, ttank->z, PROJROCKET, xv, yv, zv, accuracy * 0.75, NULL);
- addProjectile(ttank->x, ttank->y-0.1, ttank->z, PROJROCKET, xv, yv, zv, accuracy * 0.75, NULL);
- addProjectile(ttank->x, ttank->y-0.1, ttank->z, PROJROCKET, xv, yv, zv, accuracy * 0.75, NULL);
- }
-
- /**********************************/
- /* helo firing rocket */
- /**********************************/
-
- if ((tanktype == HELO) && (ttank->count <= 0) && ((rand() % 5) == 0))
- {
- ttank->count = firingDelay;
-
- xv = - (ttank->x-centerX) / 15;
- yv = ((height - bottom) * 0.5 + bottom - ttank->y) / 15;
- zv = - (ttank->z-centerZ) / 15;
-
- addProjectile( ttank->x, ttank->y-0.15, ttank->z, PROJROCKET,
- xv, yv, zv, accuracy*2, NULL);
- }
-
- /**********************************/
- /* launcher firing rocket */
- /**********************************/
-
- if ((tanktype == LAUNCHER) && (ttank->count <= 0) && ((rand() % 5) == 0))
- {
- ttank->count = firingDelay/3;
-
- yv = ((height - bottom) * 0.5 + bottom - ttank->y) / 15;
-
- xv = - (ttank->x-centerX) / 15;
- zv = - (ttank->z-centerZ) / 15;
-
- addProjectile( ttank->x, ttank->y+0.2, ttank->z, PROJROCKET,
- xv, yv, zv, accuracy*0.4, NULL);
- }
-
- /**********************************/
- /* hero firing maser / shells */
- /**********************************/
-
- if ( (tanktype == HERO))
- {
- if ((ttank->count <= 0) && (ttank->maserCount <= 0) && ((rand() % 5) == 0))
- {
- ttank->maserCount = 40;
- }
-
- if (ttank->maserCount > 0)
- {
- ttank->maserCount -= 1;
- if (ttank->maserCount == 0)
- ttank->count = firingDelay;
-
- if ((ttank->maserCount > 10) && (ttank->maserCount < 30) && (ttank->subtype == 1))
- {
- maserOn = 1;
-
- nearestMonster->energyRemaining -= 0.5;
- }
-
- if ((ttank->maserCount > 10) && (ttank->maserCount < 30) && (ttank->subtype == 0))
- {
- xv = - (ttank->x-centerX) / 15;
- yv = ((height - bottom) *0.5 + bottom - ttank->y) / 15;
- zv = - (ttank->z-centerZ) / 15;
-
- addProjectile(ttank->x, ttank->y + 0.5, ttank->z, PROJHERO, xv, yv, zv, accuracy, NULL);
- addProjectile(ttank->x, ttank->y + 0.5, ttank->z, PROJHERO, xv, yv, zv, accuracy, NULL);
- }
- }
- }
-
- /**********************************/
- /* tank firing maser */
- /**********************************/
-
- if (tanktype == MASERTANK)
- {
- if (!client)
- {
- if ((ttank->count <= 0) && (ttank->maserCount <= 0) && ((rand() % 5) == 0))
- {
- ttank->maserCount = 20 + (rand() % 5);
- }
- }
-
- if (ttank->maserCount > 0)
- {
- maserOn = 1;
- ttank->maserCount -= 1;
- if (ttank->maserCount == 0)
- ttank->count = firingDelay;
-
- nearestMonster->energyRemaining -= 0.3;
- }
- }
- }
-
- /**********************************/
- /* tank being crushed */
- /**********************************/
-
- if ((ttank->x <= (centerX+width)) && (ttank->z <= (centerZ+width)) &&
- (ttank->x >= (centerX-width)) && (ttank->z >= (centerZ-width)) &&
- (ttank->y <= height) && (ttank->y >= bottom) && (!dead))
- {
- nearestMonster->energyRemaining -= 0.75;
-
- ttank->damage -= 1;
-
- switch (tanktype)
- {
- case TANK:
- case LAUNCHER:
- case MASERTANK:
- case AIRPLANE:
- case FIGHTER:
- case HELO: addScore(tanktype, nearestMonster);
- break;
-
- case MECHAG: addScore(PARTIALM, nearestMonster);
- break;
-
- case CHH: addScore(PARTIALC, nearestMonster);
- break;
-
- case HERO: addScore(PARTIALH, nearestMonster);
- break;
- }
- }
-
- /**********************************/
- /* tank is dead */
- /**********************************/
-
- if (ttank->damage <= 0)
- {
- addBoom(ttank->x, ttank->y, ttank->z, NULL);
-
- killertank = temptank->next;
- temptank->next = temptank->next->next;
-
- switch (ttank->type)
- {
- case MECHAG:
- case CHH:
- case HERO: addScore(ttank->type, NULL);
- }
-
- if ((ttank->damage <= -99) || (tanktype == MECHAG) || (tanktype == CHH) || (tanktype == HERO) ||
- (tanktype == AIRPLANE) || (tanktype == FIGHTER))
- {
- killertank->next = slag->next;
- slag->next = killertank;
- killertank->count = 1;
- }
- else
- {
- afree(killertank, arena);
-
- }
- }
- else
- if (ttank->rad > 20 * PLANESIZE)
- {
- killertank = temptank->next;
- temptank->next = temptank->next->next;
- afree(killertank, arena);
-
- }
- else
- temptank = temptank->next;
- }
-
- /**********************************************************/
- /* if some vehicle is firing a maser then do maser sound */
- /**********************************************************/
-
- if (maserOn)
- doSound(TANKMASER);
- else
- soundKiller(TANKMASER);
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* update all the vehicles in the process of dying */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void updateSlagTanks(struct tank * allSlags)
- {
- int i, j, k;
- float x, y, z;
- float zv, xv;
- float Vplane;
- int dead;
- struct tank *killertank, *ttank, *temptank;
- int boom1, boom2;
-
- temptank = allSlags;
-
- while(temptank->next != NULL)
- {
- ttank = temptank->next;
-
- ttank->count += 1;
-
- dead = 0;
-
- if (ttank->z == 0)
- ttank->z = NEARZERO;
-
- if (((ttank->type == HELO) || (ttank->type == CHH)) && (ttank->y <= PLANEY+0.1))
- {
- addBoom(ttank->x, PLANEY, ttank->z, NULL);
- dead = 1;
- }
-
- if (((ttank->type == HELO) || (ttank->type == CHH) || (ttank->type == AIRPLANE) || (ttank->type == FIGHTER)) && (ttank->y > PLANEY))
- {
- ttank->y -= 0.04;
- }
-
- if ((ttank->type == AIRPLANE) || (ttank->type == FIGHTER))
- {
- ttank->x += sin(ttank->theta) * TANKV;
- ttank->z += cos(ttank->theta) * TANKV;
-
- if (ttank->count > 5)
- dead = 1;
- }
-
-
- if ((ttank->type != HELO) && (ttank->type != CHH) && (ttank->type != AIRPLANE)
- && (ttank->type != FIGHTER) && (ttank->count >= 40))
- {
- dead = 1;
- }
-
- x = ttank->x;
- y = ttank->y;
- z = ttank->z;
-
- if (ttank->count % 2)
- {
- switch(ttank->type){
- case MECHAG: addBoom(x + randy(0.15), y + (rand() % 1000) / 1000.0 - 0.4,
- z + randy(0.15), NULL);
- break;
- case AIRPLANE:
- case FIGHTER:
- case CHH: addBoom(x + randy(0.25), y + randy(0.25), z + randy(0.25), NULL);
- break;
- }
- }
-
-
- if (((ttank->type == AIRPLANE) || (ttank->type == FIGHTER)) && (ttank->count >= 5))
- {
- Vplane = sqrt(GRAVITY * 1.5) * 0.7071;
-
- for (i=-1;i<2;i++)
- for (j=-1;j<2;j++)
- for (k=-1;k<2;k++)
- {
- if ((rand() % 100) < 30)
- {
- zv = cos((rand() % 100) * 0.0628) * Vplane;
- xv = sin((rand() % 100) * 0.0628) * Vplane;
-
- addProjectile(x+i*0.2, y+(j*0.3), z+k*0.2, PROJTANK,
- xv, Vplane, zv, 75, NULL);
- }
- }
- }
-
- if ((ttank->type == HERO) && (ttank->count >= 40))
- {
- Vplane = sqrt(GRAVITY * 1.5) * 0.7071;
-
- for (i=-1;i<2;i++)
- for (j=-1;j<2;j++)
- for (k=-1;k<2;k++)
- {
- zv = cos((rand() % 100) * 0.0628) * Vplane;
- xv = sin((rand() % 100) * 0.0628) * Vplane;
-
- if (ttank->subtype == 1)
- {
- boom1 = rand() % 3;
- boom2 = rand() % 3;
- }
- else
- {
- boom1 = PROJTANK;
- boom2 = PROJHERO;
- }
-
- addProjectile(x+i*0.2, y+(j*0.3)+0.1, z+k*0.2, boom1,
- xv, Vplane, zv, 75, NULL);
- zv = cos(rand()%100*0.0628) * Vplane;
- xv = sin(rand()%100*0.0628) * Vplane;
-
- addProjectile(x+i*0.2, y+(j*0.3)+0.1, z+k*0.2, boom2,
- xv, Vplane, zv, 75, NULL);
- }
- }
-
- if ((ttank->type == MECHAG) && (ttank->count >= 40))
- {
- Vplane = sqrt(GRAVITY * 1.5) * 1.4;
-
- for (i=-1;i<2;i++)
- for (j=-1;j<2;j++)
- for (k=-1;k<2;k++)
- {
- zv = cos((rand() % 100) * 0.0628) * Vplane;
- xv = sin((rand() % 100) * 0.0628) * Vplane;
-
- addProjectile(x+i*0.2, y+(j*0.3)+.1, z+k*0.2, PROJTANK, xv, Vplane, zv, 75, NULL);
- }
- }
-
- if (dead)
- {
- killertank = temptank->next;
- temptank->next = temptank->next->next;
- afree(killertank, arena);
- }
- else
- temptank = temptank->next;
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* a new military vehicle is entering the game */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void addNewTank(struct targetInfo * targets, float startx, float startz, int starttype, struct tank * tanklist,
- struct tree * treelist, int mainCounter, int firingDelay, struct monsterInfo * G)
- {
- float amount,amount2;
- float xabs,zabs;
- int attempts;
- int type, side;
- int blocked;
- int howManyOfEach;
- float minX, minZ, maxX, maxZ;
- float ttankx, ttankz;
- struct targetInfo * temptarget;
- char newtype;
-
- struct targetInfo * nearestTarget;
- float radToNearestTarget;
- struct monsterInfo * nearestMonster;
- float centerX, centerZ;
- float rad;
-
- struct tank * temptank, *ttank;
- struct tree * temptree;
-
- /*********************************/
- /* decide on type of vehicle */
- /*********************************/
-
- /* disable the adding of vehicles in networked games */
-
- if (netUp || client)
- return;
-
-
- if ((starttype != -1) && (netUp || client))
- return;
-
- type = rand() % 100;
-
- if (netUp)
- {
- if (type > 50)
- newtype = MASERTANK;
- }
- else
- {
- if ((type < 28) && (mainCounter > 750))
- newtype = MASERTANK;
- else if ((type >= 28) && (type < 45))
- newtype = HELO;
- else if ((type >= 45) && (type < 60))
- newtype = LAUNCHER;
- else if ((type >= 60) && (type < 65) && (mainCounter > 1000))
- newtype = AIRPLANE;
- else if ((type >= 65) && (type < 70) && (mainCounter > 750))
- newtype = FIGHTER;
- else if ((type >= 90) && (type < 92) && (mainCounter > 3000))
- newtype = HERO;
- else if ((type >= 92) && (type < 97) && (mainCounter > 2000))
- newtype = CHH;
- else if ((type >= 97) && (mainCounter > 1250))
- newtype = MECHAG;
- else
- newtype = TANK;
- }
-
- if ((!netUp) || (newtype == MASERTANK))
- {
- /***************************************************************/
- /* ensure max of 1 bomber, 2 mechagoogelons, 2 heros on screen */
- /***************************************************************/
-
- howManyOfEach = 0;
-
- if ((newtype == AIRPLANE) || (newtype == FIGHTER) || (newtype == MECHAG) || (newtype == HERO))
- {
- for(ttank = tanklist->next; ttank != NULL; ttank = ttank->next)
- if (ttank->type == newtype)
- howManyOfEach += 1;
-
- if ((((newtype == AIRPLANE) || (newtype == FIGHTER)) && (howManyOfEach >= 1))
- || ((newtype != AIRPLANE) && (newtype != FIGHTER) && (howManyOfEach >= 2)))
- newtype = TANK;
- }
-
- /************************************/
- /* choose where vehicle will appear */
- /************************************/
-
- maxX = 0;
- maxZ = 0;
- minX = 0;
- minZ = 0;
-
-
- for(temptarget = targets->next;temptarget != NULL;temptarget = temptarget->next)
- {
- if (temptarget->x > maxX)
- maxX = temptarget->x;
- if (temptarget->x < minX)
- minX = temptarget->x;
- if (temptarget->z > maxZ)
- maxZ = temptarget->z;
- if (temptarget->z < minZ)
- minZ = temptarget->z;
- }
-
- maxX += (PLANESIZE+1);
- maxZ += (PLANESIZE+1);
- minX -= (PLANESIZE+1);
- minZ -= (PLANESIZE+1);
-
- if (fabs(maxX) > fabs(minX))
- xabs = fabs(maxX);
- else
- xabs = fabs(minX);
-
-
- if (fabs(maxZ) > fabs(minZ))
- zabs = fabs(maxZ);
- else
- zabs = fabs(minZ);
-
-
- blocked = 1;
- attempts = 0;
-
- temptank = (struct tank *) amalloc(sizeTank, arena);
-
- if (temptank != NULL)
- {
- while ((blocked) && (attempts < 1000))
- {
- attempts += 1;
- side = rand() % 4;
- amount = randy(xabs);
- amount2 = randy(zabs);
-
- switch(side)
- {
- case 0: temptank->x = amount;
- temptank->z = minZ;
- break;
-
- case 1: temptank->z = amount2;
- temptank->x = minX;
- break;
-
- case 2: temptank->x = amount;
- temptank->z = maxZ;
- break;
-
- case 3: temptank->z = amount2;
- temptank->x = maxX;
- break;
- }
-
- temptank->y = PLANEY;
-
- if (newtype == HERO)
- {
- temptank->x /= (2+randy(0.5));
- temptank->z /= (2+randy(0.5));
- }
-
- /***********************/
- /* check for obstacles */
- /***********************/
-
- ttankx = temptank->x;
- ttankz = temptank->z;
-
- /************************************************/
- /* need to compute radius to the nearest target */
- /************************************************/
-
- radToNearestTarget = 10000;
- nearestTarget = NULL;
-
- for(temptarget = targets->next; temptarget != NULL; temptarget = temptarget->next)
- {
- rad = sqrt((ttankx - temptarget->x) * (ttankx - temptarget->x) + (ttankz - temptarget->z) * (ttankz - temptarget->z));
- if (rad < radToNearestTarget)
- {
- radToNearestTarget = rad;
- nearestTarget = temptarget;
- nearestMonster = &(nearestTarget->monster);
- centerX = nearestTarget->x;
- centerZ = nearestTarget->z;
- }
- }
-
- /**********************************************/
- /* need to compute radius to player's monster */
- /**********************************************/
-
- rad = sqrt(ttankx * ttankx + ttankz * ttankz);
-
- if (rad < radToNearestTarget)
- {
- radToNearestTarget = rad;
- nearestTarget = NULL;
- nearestMonster = G;
- centerX = 0;
- centerZ = 0;
- }
-
-
- temptank->rad = radToNearestTarget;
- temptank->goforit = nearestMonster;
-
- temptank->theta = computeAngle(ttankz, centerZ, ttankx, centerX);
-
- blocked = checkForBlock(temptank, temptank->rad, temptank->theta, temptank->y);
-
- if (rad > 2 * PLANESIZE)
- blocked = 1;
- }
-
- temptank->goforit = NULL;
-
-
- /**************************************/
- /* set up specific vehicle attributes */
- /**************************************/
-
- if (attempts >= 1500)
- {
- showError("Nowhere to put a new vehicle");
- afree(temptank, arena);
- }
- else
- {
- temptank->finalR = (rand() % 1000) * 0.002 + 1.0;
- temptank->type = newtype;
-
- if (starttype != -1)
- {
- temptank->type = (char) starttype;
- temptank->x = startx;
- temptank->z = startz;
- }
-
- temptank->count = firingDelay;
- temptank->maserCount = 0;
- temptank->walking = 0;
-
- temptank->number = currentTankNumber++;
-
- temptank->subtype = (char) (rand() % 2);
-
- switch (temptank->type)
- {
- case TANK: temptank->range = 6;
- temptank->damage = 1;
- temptank->minrange = 0.5;
- temptank->speed = TANKV;
- break;
-
- case LAUNCHER: temptank->range = 4;
- temptank->damage = 1;
- temptank->minrange = 0.5;
- temptank->speed = 0.8 * TANKV;
- temptank->count = firingDelay/3;
- break;
-
- case MASERTANK: temptank->range = 3;
- temptank->damage = 1;
- temptank->minrange = 0.5;
- temptank->speed = 1.2 * TANKV;
- break;
-
- case HELO: temptank->range = 4;
- temptank->y = PLANEY + 1.0 + randy(0.2);
- temptank->damage = 1;
- temptank->minrange = 0.5;
- temptank->speed = 1.5 * TANKV;
- break;
-
- case MECHAG: temptank->range = 4.5;
- temptank->y = PLANEY +0.4;
- temptank->damage = 50;
- temptank->minrange = 0.5;
- temptank->speed = TANKV;
- break;
-
- case CHH: temptank->range = 4.5;
- temptank->y = PLANEY + 1.0 + randy(0.2);
- temptank->damage = 20;
- temptank->minrange = 0.5;
- temptank->speed = 1.2 * TANKV;
- break;
-
- case HERO: temptank->range = 4;
- temptank->y = PLANEY +0.58;
- temptank->damage = 100;
- temptank->minrange = 0.5;
- temptank->speed = TANKV;
-
- temptree = (struct tree *) amalloc(sizeof(struct tree), arena);
- if (temptree != NULL)
- {
- temptree->x = temptank->x;
- temptree->z = temptank->z;
- temptree->type = 1;
- temptree->treeshape = 33;
- temptree->y = PLANEY;
- temptree->deathCount = 0;
- temptree->death2 = -1;
- temptree->intact = 1;
- temptree->height = buildingHeight(temptree->type, temptree->treeshape);
-
- temptree->next = treelist->next;
- treelist->next = temptree;
- }
- break;
-
- case AIRPLANE: temptank->range = 1.5;
- temptank->y = PLANEY +2.5 + randy(0.25);
- temptank->damage = 1;
- temptank->minrange = 0.0;
- temptank->speed = 4 * TANKV;
- temptank->finalR = -1;
- break;
-
- case FIGHTER: temptank->range = 5;
- temptank->y = PLANEY + 2.0 + randy(0.2);
- temptank->damage = 1;
- temptank->minrange = 4.5;
- temptank->speed = 6 * TANKV;
- temptank->finalR = -1;
- temptank->count = 0;
- break;
-
- default: showError("Bogus Vehicle Type! (addNewTank)");
- break;
- }
-
- temptank->next = tanklist->next;
- tanklist->next = temptank;
- }
- }
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* update all of the explosions */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void updateBooms(struct boom * allBooms, struct tank * tanklist)
- {
- struct boom * bboom, * killerb, *tempboom;
- struct tank *temptank;
- int tanktype;
-
- tempboom = allBooms;
-
- while (tempboom->next != NULL)
- {
- bboom = tempboom->next;
- bboom->count += 1;
-
- /***********************/
- /* make some noise */
- /***********************/
-
- if ((bboom->count == 2))
- doSound(EXPLOSION);
-
- /**********************************/
- /* check for another tank hit */
- /**********************************/
-
- if ((bboom->count == 4))
- {
- for(temptank = tanklist; temptank->next != NULL; temptank = temptank->next)
- if (tankHit(temptank->next, bboom->x, bboom->y, bboom->z))
- {
- tanktype = temptank->next->type;
- temptank->next->damage -= 1;
- switch (tanktype)
- {
- case TANK:
- case LAUNCHER:
- case MASERTANK:
- case AIRPLANE:
- case FIGHTER:
- case HELO: addScore(tanktype, bboom->mine);
- break;
-
- case MECHAG: addScore(PARTIALM, bboom->mine);
- break;
-
- case CHH: addScore(PARTIALC, bboom->mine);
- break;
-
- case HERO: addScore(PARTIALH, bboom->mine);
- break;
- }
- }
- }
-
- /*******************/
- /* remove boom */
- /*******************/
-
- if (bboom->count >= 7)
- {
- killerb = tempboom->next;
- tempboom->next = tempboom->next->next;
- afree(killerb, arena);
- }
- else
- tempboom = tempboom->next;
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void buildHillPart(struct tree unitHill, int shape, float x, float z)
- {
- struct tree * temptree;
-
- temptree = (struct tree *) amalloc(sizeof(struct tree), arena);
-
- if (temptree != NULL)
- {
- *temptree = unitHill;
- temptree->treeshape = shape;
- temptree->x = x;
- temptree->z = z;
- temptree->height = buildingHeight(temptree->type, temptree->treeshape);
- temptree->number = treeID++;
-
- temptree->next = treelist->next;
- treelist->next = temptree;
- }
- }
-
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* reset everything for a new game */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void setPlayConditions()
- {
- struct boom * tempboom, *tempboom2;
- struct tank * ttank, *temptank;
- struct tree * ttree, *temptree;
- struct projectile * killer, *temp;
- struct targetInfo * ttarget, *temptarg;
-
- float x, z;
- FILE * roadFile;
- int type, shape;
- int buildingNumber;
-
- struct tree unitHill;
-
- unitHill.type = 3;
- unitHill.y = PLANEY;
- unitHill.deathCount = 0;
- unitHill.death2 = -1;
- unitHill.intact = 1;
-
- moreThanOne = 0;
-
- #ifndef MACVERSION
- setUnconnected();
- #endif
- /******************************/
- /* reset all the linked lists */
- /******************************/
-
- temptank = tanklist;
- while(temptank != NULL)
- {
- ttank = temptank;
- temptank= temptank->next;
- afree(ttank, arena);
- }
-
- tempboom = projectboom;
- while (tempboom != NULL)
- {
- tempboom2 = tempboom;
- tempboom = tempboom->next;
- afree(tempboom2, arena);
- }
-
- temp = projectFlight;
- while (temp != NULL)
- {
- killer = temp;
- temp = temp->next;
- afree(killer, arena);
- }
-
- temptank = slaglist;
- while(temptank != NULL)
- {
- ttank = temptank;
- temptank = temptank->next;
- afree(ttank, arena);
- }
-
- temptree = treelist;
- while(temptree != NULL)
- {
- ttree = temptree;
- temptree = temptree->next;
- afree(ttree, arena);
- }
-
- temptarg = targets;
- while(temptarg != NULL)
- {
- ttarget = temptarg;
- temptarg= temptarg->next;
- afree(ttarget, arena);
- }
-
-
- /******************************/
- /* set up the dummy head nodes*/
- /******************************/
-
- projectFlight = (struct projectile *) amalloc(sizeProjectile, arena);
- projectFlight->next = NULL;
-
- projectboom = (struct boom *) amalloc(sizeBoom, arena);
- projectboom->next = NULL;
-
- tanklist = (struct tank *) amalloc(sizeTank, arena);
- tanklist->next = NULL;
-
- slaglist = (struct tank *) amalloc(sizeTank, arena);
- slaglist->next = NULL;
-
- treelist = (struct tree *) amalloc(sizeof(struct tree), arena);
- treelist->next = NULL;
-
- targets = (struct targetInfo *) amalloc(sizeof(struct targetInfo), arena);
- targets->next = NULL;
-
- /************************************************************/
- /* read in data file of structures (trees, buildings, etc.) */
- /************************************************************/
-
- strcpy(fullPath, dataPath);
- strcat(fullPath, TREEFILE);
- roadFile = fopen(fullPath, "r");
-
- treeID = 0;
-
- if (roadFile == NULL)
- showError("Could not load in tree.data\n");
- else
- {
- do
- {
- temptree = (struct tree *) amalloc(sizeof(struct tree), arena);
- if (temptree != NULL)
- {
- fscanf(roadFile, "%f %f %d %d ", &x, &z, &type, &shape);
-
- temptree->x = x;
- temptree->z = z;
- temptree->type = (char) type;
- temptree->treeshape = (char) shape;
- temptree->y = PLANEY;
- temptree->deathCount = 0;
- temptree->death2 = -1;
- temptree->intact = 1;
- temptree->height = buildingHeight(temptree->type, temptree->treeshape);
- temptree->number = treeID++;
-
- if ((type == 1) && (shape == 31))
- addNewTank(targets, x, z, 1, tanklist, treelist, mainCounter, firingDelay, &Googelon);
- if ((type == 1) && (shape == 32))
- addNewTank(targets, x, z, 2, tanklist, treelist, mainCounter, firingDelay, &Googelon);
-
- if ((type == 3) && (shape == 13))
- {
- /* create all the parts of the unit-hill */
-
- buildHillPart(unitHill, 0, x, z);
- buildHillPart(unitHill, 2, x-0.6, z);
- buildHillPart(unitHill, 1, x, z+0.6);
- buildHillPart(unitHill, 4, x+0.6, z);
- buildHillPart(unitHill, 3, x, z-0.6);
-
- buildHillPart(unitHill, 7, x-0.6, z-0.6);
- buildHillPart(unitHill, 5, x+0.6, z+0.6);
- buildHillPart(unitHill, 8, x+0.6, z-0.6);
-
- *temptree = unitHill;
- temptree->treeshape = 6;
- temptree->x = x-0.6;
- temptree->z = z+0.6;
- temptree->height = buildingHeight(temptree->type, temptree->treeshape);
- }
-
- temptree->next = treelist->next;
- treelist->next = temptree;
- }
- }
- while (x || z || type || shape);
-
- treelist->next = treelist->next->next;
- afree(temptree, arena);
-
- /**************************************************************************/
- /* eliminate all trees that have been destroyed already in a network game */
- /**************************************************************************/
-
- if (netUp)
- for (temptree = treelist->next; temptree != NULL; temptree = temptree->next)
- for(buildingNumber=0; buildingNumber< buildingBoomSoFarCounter; buildingNumber++)
- if (temptree->number == buildingBoomSoFar[buildingNumber])
- temptree->intact = 0;
-
- fclose(roadFile);
- }
-
- /***********************************************/
- /* read in data file of prepositioned vehicles */
- /***********************************************/
-
- if (!netUp && !client)
- {
- strcpy(fullPath, dataPath);
- strcat(fullPath, TANKFILE);
- roadFile = fopen(fullPath, "r");
-
- if (roadFile == NULL)
- showError("Could not load in tank.data\n");
- else
- {
- do {
- fscanf(roadFile, "%f %f %d", &x, &z, &type);
-
- if (x || z || type)
- addNewTank(targets, x, z, type, tanklist, treelist, mainCounter, firingDelay, &Googelon);
- }
- while (x || z || type);
-
- fclose(roadFile);
- }
- }
-
- /*********************************/
- /* reset general game parmeters */
- /*********************************/
-
- accuracy = STARTACCURACY;
- arrivalTime = ARRIVALRATE;
- firingDelay = STARTFIRINGDELAY;
- mainCounter = 0;
-
- killtanks = killmtanks = killhelos = 0;
- killCHHs = killheros = killmechags = 0;
- killlaunchers = killfighters = killplanes = 0;
-
- xrot = xsaverot = 300;
- yrot = ysaverot = 0;
-
- globalxshift = 0;
- globalzshift = 0;
-
- if (!netUp && !client)
- buildingBoomSoFarCounter = 0;
-
- Googelon = resetMonsterParameters(Googelon);
-
-
- /***********************************************************
- code to print out the state of the shared memory arena
-
- {
- struct mallinfo mi;
-
- mi = amallinfo(arena);
- fprintf(stderr, "--------------------------------------------------------------------------------\n");
- fprintf(stderr, "%8d %8d %8d %8d %8d %8d %8d %8d %8d -start\n",
- mi.arena, mi.ordblks, mi.smblks, mi.hblkhd, mi.hblks,
- mi.usmblks, mi.fsmblks, mi.uordblks, mi.fordblks);
- fprintf(stderr, "--------------------------------------------------------------------------------\n");
- fflush(stderr);
- }
-
- ***********************************************************/
- }
-
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void addRandomTarget()
- {
- struct monsterInfo newMonster;
- struct targetInfo * nother, * temp;
- int i, j, k;
- float Vplane;
-
- /**************************************/
- /* is there room for another monster? */
- /**************************************/
-
- for (i=0, temp=targets->next; temp != NULL; i++,temp=temp->next);
-
- if (i < MAXTARGETS)
- {
- moreThanOne = 1;
-
- /******************************/
- /* generate a random monster */
- /******************************/
-
- newMonster.monster = rand() % 4;
-
- /************************************/
- /* reset general monster parmeters */
- /************************************/
-
- newMonster = resetMonsterParameters(newMonster);
-
- newMonster.energyRemaining = MAXLIFE / 2;
-
- nother = (struct targetInfo *) amalloc(sizeof(struct targetInfo), arena);
-
- if (nother != NULL)
- {
- nother->monster = newMonster;
-
- /********************************************/
- /* declare this is not a networked monster */
- /********************************************/
-
- nother->net_clientFrom = COMPUTER_MONSTER;
-
- do
- nother->x = rand() % (PLANESIZE-1);
- while (fabs(nother->x) < 2);
-
- do
- nother->z = rand() % (PLANESIZE-1);
- while (fabs(nother->z) < 2);
-
- nother->next = targets->next;
- targets->next = nother;
-
- Vplane = sqrt(GRAVITY * 1.5) * 0.7071;
-
- for (i=-1;i<2;i++)
- for (j=0;j<3;j++)
- for (k=-1;k<2;k++)
- if ((rand() % 100) < 75)
- {
- addProjectile( nother->x+i*.35, (newMonster.height * 0.5 + newMonster.bottom * 0.5)+(j*.35), nother->z+k*.35, 2,
- sin(randy(PI)) * Vplane, Vplane, cos(randy(PI)) * Vplane, 75, &(nother->monster));
- addProjectile( nother->x+i*.35, (newMonster.height * 0.5 + newMonster.bottom * 0.5)+(j*.35), nother->z+k*.35, 2,
- sin(randy(PI)) * Vplane, Vplane, cos(randy(PI)) * Vplane, 75, &(nother->monster));
- }
- }
- }
-
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void newPlayerName(char * newName)
- {
- sscanf(newName,"%s",playerName);
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* initialize everything at the start of battalion */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void initialization()
- {
- struct passwd *passwd;
- struct tm* theTime;
- FILE * roadFile;
- FILE * hiScoreFile;
- float garb1, garb2;
- int i, garb3;
- GLint gdtmp;
- GLint tmp[4];
- GLenum type;
- char textBuffer[80];
- char * dataPtr;
- char * playerPointer;
- char scoredataPath[MAXPATH];
- char garbage;
-
-
- /******************************/
- /* set up sone network stuff */
- /******************************/
-
- #ifndef MACVERSION
-
- setHostAddr("");
- setPortNumber(DEFAULT_PORT);
-
- setUnconnected();
- #endif
-
- netUp = 0;
- client = 0;
-
- buildingBoomSoFarCounter = 0;
- buildingBoomThisFrameCounter = 0;
- currentTankNumber = 1;
- biggestTankNumberSent = 0;
-
- totalCounter = 0;
-
- /************************************/
- /* set up memory arena */
- /************************************/
-
- #ifdef SGIVERSION
-
- sharedmem = calloc(1, ARENASIZE);
- arena = acreate(sharedmem, ARENASIZE, 0, NULL, NULL);
- amallopt(M_FREEHD, 1, arena);
- amallopt(M_CLRONFREE, 0, arena);
- amallopt(M_MXFAST, 16, arena);
-
- #endif
-
- sizeBoom = sizeof(struct boom);
- sizeTank = sizeof(struct tank);
- sizeProjectile = sizeof(struct projectile);
-
- /************************************/
- /* set up the window */
- /************************************/
-
- /* TK_INDIRECT gives me a 50% boost in speed! on a an indy */
-
- /* removing the depth buffer from this line has no effect */
- /* switching to TK_SINGLE almost works in Vector graphics mode - BIG speedup there */
-
- type = TK_INDIRECT | TK_DOUBLE /* TK_SINGLE*/ | TK_RGB| TK_DEPTH;
- tkInitDisplayMode(type);
-
- #ifdef MESAVERSION
- tkInitPosition(-1, -1, 352, 275);
- #else
- tkInitPosition(-1, -1, 640, 500);
- #endif
-
- #ifdef MESA_TK_VERSION
- tkIdleFunc(id);
- tkExposeFunc(reshape);
- tkReshapeFunc(reshape);
- tkKeyDownFunc(processKey);
- #ifdef AMIGAVERSION
- tkKeyUpFunc(processKeyRelease);
- #endif
- tkMouseDownFunc(MouseDown);
- tkMouseUpFunc(MouseUp);
- #endif
-
- if (tkInitWindow("battalion") == GL_FALSE)
- {
- fprintf(stderr, "could not open a window\n");
- exit(1);
- }
-
- pointerGrab = 0;
-
- /************************************/
- /* get information on the player */
- /************************************/
-
- strcpy(playerName, "Anonymous");
-
- #ifdef AMIGAVERSION
- if (!(playerPointer = getenv("USER")))
- playerPointer = getenv("LOGNAME");
- #else
- playerPointer = cuserid(NULL);
- if (playerPointer == NULL)
- playerPointer = getlogin();
- #endif
-
- if (playerPointer != NULL)
- /*strcpy(playerName, playerPointer);*/
-
- /* this ensures the player name is a single word */
- sscanf(playerPointer,"%s",playerName);
- if (strlen(playerName) > 9)
- playerName[9] = 0;
-
- #if defined(MACVERSION) || defined(AMIGAVERSION)
- playerHome[0] = '\0';
- #ifdef MACVERSION
- setPlayerName(playerName);
- #endif
- #else
-
- passwd = getpwuid(getuid());
- if (passwd != NULL && passwd->pw_dir != NULL && *(passwd->pw_dir) != '\0')
- {
- strcpy(playerHome, passwd->pw_dir);
- playerHome[strlen(playerHome)] = '\0';
- }
- else
- {
- playerHome[0] = '\0';
- }
- #endif
-
- /************************************/
- /* set up the graphics */
- /************************************/
-
- /* if line widths are integral Mesa chokes in a large window */
- glLineWidth(1.01);
-
- glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
- glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
- glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST);
-
- glFogi(GL_FOG_MODE, GL_LINEAR);
-
- glDisable(GL_POINT_SMOOTH);
- glDisable(GL_LINE_SMOOTH);
- glDisable(GL_POLYGON_SMOOTH);
-
- glDisable(GL_ALPHA_TEST);
- glDisable(GL_AUTO_NORMAL);
- glDisable(GL_BLEND);
- glDisable(GL_COLOR_MATERIAL);
- glDisable(GL_LIGHTING);
- glDisable(GL_LINE_STIPPLE);
- glDisable(GL_NORMALIZE);
- glDisable(GL_POLYGON_STIPPLE);
-
- glDisable(GL_FOG);
-
- glCullFace(GL_BACK);
- glEnable(GL_CULL_FACE);
-
-
- /* this helps zbuffering in mesa */
-
- #ifdef MESAVERSION
- glDepthRange(0,1);
- glDepthFunc(GL_LEQUAL);
- #endif
-
-
- glPointSize(2);
- goToHighDetail();
-
- glMatrixMode(GL_MODELVIEW);
-
-
- glClearDepth(1);
- glClearColor(0, 0, 0, 1);
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glDrawBuffer(GL_BACK);
-
- /**************************/
- /* stereo stuff */
- /**************************/
-
- /* OGLXXX
- * getsize not supported -- See Window Manager
- * getsize(&windowSizeX, &windowSizeY);
- */
-
- /* OGLXXX
- * getorigin not supported -- See Window Manager
- * getorigin(&windowOriginX, &windowOriginY);
- */
-
- glGetIntegerv(GL_VIEWPORT, tmp);
- viewL=tmp[0];
- viewR=tmp[0]+tmp[2]-1;
-
- /* OGLXXX
- * getmonitor not supported
- * getmonitor()
- */
- monitorType = 0; /*THIS IS BAD*/
-
-
- monsterLookat = makeMonsterLookat();
- overviewLookat = makeOverviewLookat();
-
- /*************************/
- /* initialize indicators */
- /*************************/
-
- alone = 0;
- noSound = 0;
- turnSoundOff();
- turnMusicOff();
- no3D = 0;
- mode3D = 0;
- doBigClear = 0;
- showOptions = 0;
- backdrop = 0;
- showframes = 0;
- paused = 0;
-
- #ifdef MESAVERSION
- lod = 0;
- #else
- lod = 1;
- #endif
-
- #ifdef DETAIL
- lod = DETAIL;
- #endif
-
- mode = DEMOMODE;
- view = OMNISCIENTVIEW;
- oldview = 99;
-
- timePaused = 0;
- time3d = 0;
- timeSound = 0;
- timeMusic = 0;
- timeDetail = 0;
-
- mapHeight = 35;
-
- /************************************/
- /* initialize all the linked lists */
- /************************************/
-
- projectFlight = NULL;
- projectboom = NULL;
- tanklist = NULL;
- slaglist = NULL;
- treelist = NULL;
-
- roadSystem = NULL;
-
- initSounds();
-
- /************************************/
- /* get the current date/time */
- /************************************/
-
- beg = time(NULL);
- theTime = localtime(&beg);
-
- /*************************************/
- /* if its xmas use the xmas graphics */
- /*************************************/
-
- if ((theTime->tm_mday == 25) && (theTime->tm_mon == 11))
- itsChristmas = 1;
- else
- itsChristmas = 0;
-
-
- /**************************************/
- /* initialize random number generator */
- /**************************************/
-
- srand( (unsigned) beg);
-
-
- /************************************/
- /* check graphics hardware */
- /************************************/
-
- glGetIntegerv(GL_DEPTH_BITS, &gdtmp);
- if (gdtmp == GL_FALSE)
- showError("Z-buffer not available on this machine");
-
- glGetIntegerv(GL_RED_BITS, &gdtmp);
- if (gdtmp == GL_FALSE)
- showError("Double buffered RGB not available on this machine");
-
- glGetIntegerv(GL_STEREO, &gdtmp);
- if (gdtmp == GL_FALSE)
- no3D = 1;
-
- /********************************************/
- /* find where all the data files are stored */
- /********************************************/
-
- roadFile = NULL;
-
- #ifdef MACVERSION
- strcpy(dataPath, ":battalion.data:");
- strcpy(fullPath, dataPath);
- strcat(fullPath, "battalion.sho");
- roadFile = fopen(fullPath, "rb");
- #else
-
- dataPtr = getenv("BATTALIONDATADIR");
- if (dataPtr != NULL)
- {
- strcpy(dataPath, dataPtr);
-
- if (dataPath[strlen(dataPath)-1] != '/')
- strcat(dataPath, "/");
-
- strcpy(fullPath, dataPath);
- strcat(fullPath, "battalion.sho");
- roadFile = fopen(fullPath, "rb");
- }
- #endif
-
- if (roadFile != NULL)
- {
- fclose(roadFile);
- }
- else
- {
- /* since the Indizone version is missing Techs' sound we can't use this.
-
- roadFile = fopen("/usr/demos/IndiZone/.data/battalion/battalion.sho", "rb");
- if (roadFile != NULL)
- {
- strcpy(dataPath, "/usr/demos/IndiZone/.data/battalion/");
- fclose(roadFile);
- }
- else
- */
- {
- roadFile = fopen(DATADIR "/battalion.sho", "rb");
- if (roadFile != NULL)
- {
- strcpy(dataPath, DATADIR "/");
- fclose(roadFile);
- }
- else
- showError("Could not find the data files\n");
- }
- }
-
- /************************************/
- /* build all the objects */
- /************************************/
-
- makeObjects(dataPath);
-
- /************************************/
- /* read in data file of roads */
- /************************************/
-
- strcpy(fullPath, dataPath);
- strcat(fullPath, ROADFILE);
-
- roadFile = fopen(fullPath, "r");
-
- if (roadFile == NULL)
- showError("Could not load in road.data\n");
- else
- {
-
- /* find out how many entries are in the road file */
-
- i = 0;
- do
- {
- fscanf(roadFile, "%f %f %d", &garb1, &garb2, &garb3);
- i += 1;
- }
- while (garb1 || garb2 || garb3);
-
- fclose(roadFile);
-
- roadSystem = (struct road *) acalloc(i, sizeof(struct road), arena);
- if (roadSystem == NULL)
- showError("Could not allocate array for road.data\n");
- else
- {
- roadSystem[i-1].type = NULLROAD;
-
- roadFile = fopen(fullPath, "r");
- i = i - 2;
- for(; i >= 0; i--)
- {
- fscanf(roadFile, "%f %f %d", &garb1, &garb2, &garb3);
- roadSystem[i].x = garb1;
- roadSystem[i].y = garb2;
- roadSystem[i].type = (char) garb3;
- }
- fclose(roadFile);
- }
- }
-
- /***************************************/
- /* see if this machine can play sounds */
- /***************************************/
-
- checkSound(dataPath);
-
-
- /************************************/
- /* see if a high score file exists */
- /* if not try and create one */
- /************************************/
-
- multipleHighScores = 1;
-
- /* If BATTALIONSCOREUNIQUE is defined, only put the
- top entry for each user in the high score list.
- */
-
- if (getenv("BATTALIONSCOREUNIQUE"))
- {
- multipleHighScores = 0;
- }
-
- hiScoreFile = NULL;
-
- dataPtr = getenv("BATTALIONSCOREDIR");
- if (dataPtr != NULL)
- strcpy(scoredataPath, dataPtr);
- else
- #ifndef AMIGAVERSION
- strcpy(scoredataPath, "/usr/tmp");
- #else
- strcpy(scoredataPath, "RAM:T");
- #endif
-
- if (scoredataPath[strlen(scoredataPath)-1] != '/')
- strcat(scoredataPath, "/");
-
- strcpy(scorefullPath, scoredataPath);
-
- #ifdef MACVERSION
- strcpy(scorefullPath,"");
- #endif
-
- strcat(scorefullPath, "battalion_hiscore");
- hiScoreFile = fopen(scorefullPath, "r");
-
- if (hiScoreFile == NULL)
- {
- hiScoreFile = fopen(scorefullPath, "w");
-
- if (hiScoreFile == NULL)
- {
- sprintf(textBuffer, "Couldn't create high score file: %s", scorefullPath);
- showError(textBuffer);
- }
- else
- {
- for(i=0;i<12;i++)
- fprintf(hiScoreFile, "-1 -\n");
-
- G[0].number = G[1].number = G[2].number = -1;
- F[0].number = F[1].number = F[2].number = -1;
- V[0].number = V[1].number = V[2].number = -1;
- T[0].number = T[1].number = T[2].number = -1;
-
- G[0].name[0] = G[1].name[0] = G[2].name[0] = 0;
- F[0].name[0] = F[1].name[0] = F[2].name[0] = 0;
- V[0].name[0] = V[1].name[0] = V[2].name[0] = 0;
- T[0].name[0] = T[1].name[0] = T[2].name[0] = 0;
-
- fclose(hiScoreFile);
-
- # ifdef SOLARIS
-
- /* Make hiscore file read/writeable for everyone */
- if (chmod(scorefullPath, 0666))
- {
- sprintf(textBuffer, "Couldn't change permission of high score file: %s", hiScoreFile);
- showError(textBuffer);
- }
- # endif
- }
- }
- else
- {
- fscanf(hiScoreFile, "%d%c%s", &(G[0].number), &garbage, G[0].name);
- fscanf(hiScoreFile, "%d%c%s", &(G[1].number), &garbage, G[1].name);
- fscanf(hiScoreFile, "%d%c%s", &(G[2].number), &garbage, G[2].name);
-
- fscanf(hiScoreFile, "%d%c%s", &(V[0].number), &garbage, V[0].name);
- fscanf(hiScoreFile, "%d%c%s", &(V[1].number), &garbage, V[1].name);
- fscanf(hiScoreFile, "%d%c%s", &(V[2].number), &garbage, V[2].name);
-
- fscanf(hiScoreFile, "%d%c%s", &(F[0].number), &garbage, F[0].name);
- fscanf(hiScoreFile, "%d%c%s", &(F[1].number), &garbage, F[1].name);
- fscanf(hiScoreFile, "%d%c%s", &(F[2].number), &garbage, F[2].name);
-
- fscanf(hiScoreFile, "%d%c%s", &(T[0].number), &garbage, T[0].name);
- fscanf(hiScoreFile, "%d%c%s", &(T[1].number), &garbage, T[1].name);
- fscanf(hiScoreFile, "%d%c%s", &(T[2].number), &garbage, T[2].name);
-
- fclose(hiScoreFile);
- }
-
-
- /************************************/
- /* pick a random monster to start */
- /************************************/
-
- Googelon.monster = rand() % 4;
-
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* go to 3d-video mode */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void goto3d(void)
- {
- GLint gdtmp;
-
- /* OGLXXX
- * getsize not supported -- See Window Manager
- * getsize(&windowWide, &windowTall);
- */
-
- /* OGLXXX
- * getorigin not supported -- See Window Manager
- * getorigin(&windowLeft, &windowTop);
- */
-
- /* OGLXXX
- * getgdesc other posiblilties:
- * glxGetConfig();
- * glxGetCurrentContext();
- * glxGetCurrentDrawable();
- * GLint gdtmp;
- */
- if ((glGetIntegerv(GL_STEREO, &gdtmp), gdtmp))
- {
- /* OGLXXX
- * setmonitor not supported
- * setmonitor(STR_RECT)
- */
-
- /* OGLXXX
- * getgdesc other posiblilties:
- * glxGetConfig();
- * glxGetCurrentContext();
- * glxGetCurrentDrawable();
- * GLint gdtmp;
- * getgdesc other posiblilties:
- * glxGetConfig();
- * glxGetCurrentContext();
- * glxGetCurrentDrawable();
- * GLint gdtmp;
- * see window manager
- * see window manager
- * prefposition not supported -- See Window Manager
- * prefposition(0, (glGetIntegerv(XXX_XPMAX, &gdtmp), gdtmp), 0, (glGetIntegerv(XXX_YPMAX, &gdtmp), gdtmp))
- */
-
- }
- /* OGLXXX
- * winconstraints not supported -- See Window Manager
- * winconstraints()
- */
- /* OGLXXX
- * setvaluator not supported -- See Events
- * setvaluator(MOUSEY, YMAXSTEREO/2, 0, YMAXSTEREO)
- */
-
- mode3D = 1;
- doBigClear = 2;
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* go to 1d-video mode */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void goto1d(void)
- {
- GLint gdtmp;
-
- /* OGLXXX
- * getgdesc other posiblilties:
- * glxGetConfig();
- * glxGetCurrentContext();
- * glxGetCurrentDrawable();
- * GLint gdtmp;
- */
- if ((glGetIntegerv(GL_STEREO, &gdtmp), gdtmp))
- /* OGLXXX
- * setmonitor not supported
- * setmonitor((short) monitorType)
- */
-
- /* OGLXXX
- * winposition not supported -- See Window Manager
- * winposition(windowLeft, windowLeft + windowWide, windowTop, windowTop + windowTall)
- */
-
- /* OGLXXX
- * keepaspect not supported -- See Window Manager
- * keepaspect(1280, 1000)
- */
-
- /* OGLXXX
- * winconstraints not supported -- See Window Manager
- * winconstraints()
- */
-
- /* OGLXXX
- * getgdesc other posiblilties:
- * glxGetConfig();
- * glxGetCurrentContext();
- * glxGetCurrentDrawable();
- * GLint gdtmp;
- * see window manager
- * getvaluator not supported -- See Events
- * getvaluator(MOUSEY)
- * setvaluator not supported -- See Events
- * setvaluator(MOUSEY, (short) ???, 0, (short) (glGetIntegerv(XXX_YPMAX, &gdtmp), gdtmp))
- */
-
- mode3D = 0;
- }
-
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* check the current location of the mouse in the window */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void checkMouse()
- {
- int x, y;
- float offsetY;
-
- Googelon.monsterGo = Googelon.monsterBack = 0;
-
- if (Gfor)
- Googelon.monsterGo = 1;
-
- if (Gbak)
- Googelon.monsterBack = 1;
-
- if ((mode == PLAYMODE) && !paused)
- {
- tkGetMouseLoc(&x, &y);
-
- offsetX = 2*(x / (float) viewW - 0.5);
- offsetY = 2*(y / (float) viewH - 0.5);
-
-
- if (offsetX > 1)
- offsetX = 1;
- else if (offsetX < -1)
- offsetX = -1;
-
- if (offsetY > 1)
- offsetY = 1;
- else if (offsetY < -1)
- offsetY = -1;
-
- if (fabs(offsetX) > 0.2)
- {
- Googelon.headHorzRotate -= (int) (offsetX * Googelon.xspeed);
- Googelon.monsterMoving = 1;
- }
-
- if (offsetY > 0.3)
- Googelon.monsterBack = 1;
- else if (offsetY < -0.3)
- Googelon.monsterGo = 1;
- }
-
- Gfor = 0;
- Gbak = 0;
- Gturn = 0;
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- GLenum mouseKey(int key, GLenum mask)
- {
- if ((mode == DEMOMODE) && (showOptions))
- processKey(key,mask);
-
- return GL_TRUE;
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- GLenum MouseDown(int mouseX, int mouseY, GLenum button)
- {
- int xloc,yloc;
-
- xloc = mouseX;
- yloc = mouseY;
-
- if ((mode == PLAYMODE) && !paused && (button == TK_LEFTBUTTON))
-
- Googelon.beamOn = 1;
-
- return 0;
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- GLenum MouseUp(int mouseX, int mouseY, GLenum button)
- {
- int xloc,yloc;
-
- xloc = mouseX;
- yloc = mouseY;
-
- if ((mode == PLAYMODE) && (button == TK_LEFTBUTTON))
- Googelon.beamOn = 0;
-
- return 0;
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void demoKeys(int key)
- {
- switch(key)
- {
- case TK_SPACE: showOptions = 1;
- break;
-
- case TK_6: mode = PLAYMODE;
- showOptions = 0;
- Googelon.monster = GOOGELON;
- setPlayConditions();
- break;
-
- case TK_7: mode = PLAYMODE;
- showOptions = 0;
- Googelon.monster = TECHS;
- setPlayConditions();
- break;
-
- case TK_8: mode = PLAYMODE;
- showOptions = 0;
- Googelon.monster = VAPOUR;
- setPlayConditions();
- break;
-
- case TK_9: mode = PLAYMODE;
- showOptions = 0;
- Googelon.monster = FLUTTER;
- setPlayConditions();
- break;
-
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void doMonsterView()
- {
- view = MONSTERVIEW;
-
- #ifdef MACVERSION
- updateMonsterMenu(imonsterview);
- #endif
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void doOmniscientView()
- {
- view = OMNISCIENTVIEW;
- if (oldview != OMNISCIENTVIEW)
- {
- yrot = ysaverot;
- xrot = xsaverot;
- }
-
- #ifdef MACVERSION
- updateMonsterMenu(ioverview);
- #endif
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void doArmyView()
- {
- view = ARMYVIEW;
-
- #ifdef MACVERSION
- updateMonsterMenu(iarmyview);
- #endif
- }
-
- void doMapView()
- {
- view = MAPVIEW;
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void playKeys(int key)
- {
- switch(key)
- {
- case TK_1: doMonsterView();
- break;
-
- case TK_2: doOmniscientView();
- break;
-
- case TK_3: doArmyView();
- break;
-
- case TK_4: doMapView();
- break;
-
- case TK_i:
- case TK_I: xrot -= 8;
- break;
-
- case TK_j:
- case TK_J: yrot += 8;
- break;
-
- case TK_k:
- case TK_K: xrot += 8;
- break;
-
- case TK_l:
- case TK_L: yrot -= 8;
- break;
-
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void playNoPauseKeys(int key)
- {
- switch(key)
- {
- case TK_LEFT: offsetX = -1/*-0.5*/;
- Googelon.headHorzRotate -= (int) (offsetX * Googelon.xspeed);
- Gturn = 1;
- break;
-
- case TK_RIGHT: offsetX = 1/*0.5*/;
- Googelon.headHorzRotate -= (int) (offsetX * Googelon.xspeed);
- Gturn = 1;
- break;
-
- case TK_UP: Gfor = 1;
- break;
-
- case TK_DOWN: Gbak = 1;
- break;
-
-
- case TK_a:
- case TK_A: Googelon.headVertRotate += 15;
- break;
-
- case TK_y: /* for german keyboard */
- case TK_Y:
- case TK_z:
- case TK_Z: Googelon.headVertRotate -= 15;
- break;
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- GLenum processKey(int key, GLenum mask)
- {
- GLenum keyMask;
-
- keyMask = mask;
-
- if (mode == DEMOMODE)
- demoKeys(key);
-
- if ((mode == PLAYMODE) && !paused)
- playNoPauseKeys(key);
-
- if (mode == PLAYMODE)
- playKeys(key);
-
- switch(key)
- {
- case TK_CONTROL_L:
- #ifndef MACVERSION
- Googelon.beamOn = 1;
- #else
- /* temporary hack to get the control key to work on the mac since
- I cant seem to get it to register a keyup for the control key */
- Googelon.beamOn = ! Googelon.beamOn;
- #endif
- break;
-
- case TK_p:
- case TK_P: if (now > (timePaused+1))
- {
- paused = !paused;
- timePaused = now;
- }
- break;
-
- case TK_m:
- case TK_M: if (now > (timeMusic+1))
- {
- toggleMusic();
- timeMusic = now;
- }
- break;
-
- case TK_s:
- case TK_S: if (now > (timeSound+1))
- {
- toggleSound();
- timeSound = now;
- }
- break;
-
- case TK_d:
- case TK_D: if (now > (timeMusic+1))
- {
- lod++;
- if (lod > 2)
- lod = -1;
- timeDetail = now;
-
- #ifdef MACVERSION
- switch (lod){
- case -1: updateDetailMenu(ivector); break;
- case 0: updateDetailMenu(ilowdetail); break;
- case 1: updateDetailMenu(imeddetail); break;
- case 2: updateDetailMenu(ihighdetail); break;
- }
- #endif
-
-
- if (lod == -1)
- {
- goToLowDetail();
- }
- else
- {
- goToHighDetail();
- }
-
-
- }
- break;
-
- #ifdef SGIVERSION
- case TK_h:
- case TK_H:
- if (mode3D)
- goto1d();
- system("showcase -bfv battalion.data/battalion.sho");
- break;
- #endif
-
- case TK_g:
- case TK_G:
-
- #if !defined(MACVERSION) && !defined(AMIGAVERSION)
- if (pointerGrab)
- unGrabPointer();
- else
- grabPointer();
- pointerGrab = !pointerGrab;
- #endif
- break;
-
- case TK_q:
- case TK_Q: if (mapHeight > 1)
- mapHeight -= 1;
- break;
-
- case TK_w:
- case TK_W: if (mapHeight < 45)
- mapHeight += 1;
- break;
-
- case TK_ESCAPE: goto1d();
- #if !defined(MACVERSION) && !defined(AMIGAVERSION)
- if (pointerGrab)
- unGrabPointer();
- #endif
- #ifdef MESA_TK_VERSION
- tkQuit();
- #else
- exit(0);
- #endif
- }
-
-
- return GL_TRUE;
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* processKeyRelease */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- /* detects when the control key is released, to turn off the beam.
- */
-
- #ifndef AMIGAVERSION
- GLenum processKeyRelease(int key)
- #else
- GLenum processKeyRelease(int key,GLenum mask)
- #endif
- {
- /* this seems to work on the 68K version but not the PPC version */
-
- if (key == TK_CONTROL_L)
- Googelon.beamOn = 0;
- return GL_TRUE;
- }
-
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* check the user's input */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*
- void checkInput ()
- {
- int yes3D, no3D, yesDump;
-
- yes3D = no3D = yesDump = 0;
-
-
-
- case VKEY: if (now > (time3d + 4))
- {
- if (mode3D)
- no3D = 1;
- else
- yes3D = 1;
- time3d = now;
- }
- do not put a qreset here!
- break;
-
-
- if ((yes3D) && (!no3D))
- goto3d();
-
- if ((mode3D) && (no3D))
- goto1d();
-
- }
- */
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* deal with a dead monster (not necessarily your monster) */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void updateDeadMonster(float x, float z, struct monsterInfo * thaMonster)
- {
- float Vplane;
- int i, j, k;
-
- thaMonster->monsterIsDead = 1;
-
- if ((x==0) && (z==0)) /* its the player's monster that dies */
- view = OMNISCIENTVIEW;
-
- if (thaMonster->energyRemaining < 0)
- thaMonster->energyRemaining = 0;
-
- /************************/
- /* update dying monster */
- /************************/
-
- thaMonster->deadCount += 1;
-
- if (thaMonster->deadCount > 45)
- {
- thaMonster->deadCount = 45;
- thaMonster->timeDead += 1;
- }
-
- if (thaMonster->deadCount == 44)
- {
- if (thaMonster->monster != VAPOUR)
- {
- doSound(CRASH);
- }
-
- if (thaMonster->monster == FLUTTER)
- {
- addProjectile( x-0.2, PLANEY+0.25, z+0.2, 3, 0, -0.001, 0, 10000, NULL);
- addProjectile( x+0.2, PLANEY+0.25, z+0.2, 3, 0, -0.001, 0, 10000, NULL);
- addProjectile( x , PLANEY+0.25, z, 3, 0, -0.001, 0, 10000, NULL);
- addProjectile( x-0.2, PLANEY+0.25, z-0.2, 3, 0, -0.001, 0, 10000, NULL);
- addProjectile( x+0.2, PLANEY+0.25, z-0.2, 3, 0, -0.001, 0, 10000, NULL);
- }
-
- if (thaMonster->monster == TECHS)
- {
- addProjectile( x-0.2, PLANEY+0.2, z+0.2, 3, 0, -0.001, 0, 10000, NULL);
- addProjectile( x+0.2, PLANEY+0.2, z+0.2, 3, 0, -0.001, 0, 10000, NULL);
- addProjectile( x , PLANEY+0.2, z, 3, 0, -0.001, 0, 10000, NULL);
- addProjectile( x-0.2, PLANEY+0.2, z-0.2, 3, 0, -0.001, 0, 10000, NULL);
- addProjectile( x+0.2, PLANEY+0.2, z-0.2, 3, 0, -0.001, 0, 10000, NULL);
-
- Vplane = sqrt(GRAVITY * 1.5) * 0.7071;
-
- for (i=-1;i<2;i++)
- for (j=0;j<3;j++)
- for (k=-1;k<2;k++)
- if ((rand() % 100) < 75)
- {
- addProjectile( x+i*.35, PLANEY+(j*.35)+.1, z+k*.35, 0,
- sin(randy(PI)) * Vplane, Vplane, cos(randy(PI)) * Vplane, 75, NULL);
- }
- }
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* make the vapour 'vapourous' */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void updateVapourLook(float a[MAXTRIBUTES][5], int monsterIsDead)
- {
- register int i, j;
- int again;
-
- for(i=0; i<MAXTRIBUTES; i++) /* needed not only for vapour - re options menu */
- {
- a[i][4] += 0.1;
-
- if (a[i][4] >= 3.2)
- {
- a[i][4] = 0;
-
- again = 1;
- while (again && !monsterIsDead)
- {
- a[i][0] = randy(0.20);
- a[i][1] = PLANEY + 0.55 + randy(0.5);
- a[i][2] = randy(0.20);
-
- again = 0;
- for(j=0; (j < MAXTRIBUTES) && !again; j++)
- {
- if ((i != j)
- && (fabs(a[i][0] - a[j][0]) < 0.12)
- && (fabs(a[i][1] - a[j][1]) < 0.12)
- && (fabs(a[i][2] - a[j][2]) < 0.12))
- again = 1;
- }
- }
- }
- a[i][3] = sin(a[i][4]) * 0.2;
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* update all of the other monsters currently in the game */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void updateTargets()
- {
- struct tree * temptree;
- struct tank * temptank;
- struct targetInfo * temptarget;
- struct targetInfo * temptarget2;
- struct monsterInfo thaMonster;
- struct tree ttree;
- float mAngle, obsangle;
- float mRad, mAng;
- float tx, tz;
- float trad, rad;
- int blocked, nearAngle;
-
- for(temptarget = targets->next; temptarget != NULL; temptarget = temptarget->next)
- {
- thaMonster = temptarget->monster;
- tx = temptarget->x;
- tz = temptarget->z;
-
- /************************************/
- /* deal with the networked monsters */
- /************************************/
-
- if (temptarget->net_clientFrom != COMPUTER_MONSTER)
- {
- thaMonster.energyRemaining = temptarget->net_energyRemaining;
- thaMonster.beamOn = temptarget->net_beamOn;
-
- nearAngle = temptarget->net_headHorzRotate;
- if (fabs(thaMonster.headHorzRotate - (temptarget->net_headHorzRotate + 3600)) < fabs(thaMonster.headHorzRotate - nearAngle))
- nearAngle = temptarget->net_headHorzRotate + 3600;
- if (fabs(thaMonster.headHorzRotate - (temptarget->net_headHorzRotate - 3600)) < fabs(thaMonster.headHorzRotate - nearAngle))
- nearAngle = temptarget->net_headHorzRotate - 3600;
-
- thaMonster.headHorzRotate = 0.7 * thaMonster.headHorzRotate + 0.3 * nearAngle;
-
- thaMonster.headVertRotate = 0.9 * thaMonster.headVertRotate + 0.1 * temptarget->net_headVertRotate;
- temptarget->x = 0.9 * temptarget->x + 0.1 * temptarget->net_x;
- temptarget->z = 0.9 * temptarget->z + 0.1 * temptarget->net_z;
-
- if (thaMonster.energyRemaining > 0)
- {
- thaMonster.rot1 = cos(thaMonster.moveCount) * 0.02;
- thaMonster.rot2 = sin(thaMonster.moveCount) * 0.05;
- }
- else
- {
- updateDeadMonster(temptarget->x, temptarget->z, &thaMonster);
- }
-
- thaMonster.monsterMoving = 1;
- thaMonster.moveCount += 1;
-
- updateVapourLook(thaMonster.a, thaMonster.monsterIsDead);
-
- /************************************************/
- /* update the weapons of the networked monsters */
- /************************************************/
-
- if (thaMonster.beamOn)
- switch (thaMonster.monster){
- case GOOGELON: updateBeam(&Googelon, targets, temptarget->x, temptarget->z, tanklist, allTreesEverywherePtrs,
- numTreesEverywhere, &thaMonster);
-
- thaMonster.energyRemaining -= 0.15;
- break;
-
- case TECHS: updateGun(temptarget->x, temptarget->z, thaMonster.headHorzRotate,
- thaMonster.headVertRotate, mainCounter, &(temptarget->monster));
- thaMonster.energyRemaining -= 0.09;
- break;
-
- case VAPOUR: updateVap(temptarget->x, temptarget->z, mainCounter, &(temptarget->monster));
- thaMonster.energyRemaining -= 0.1;
- break;
-
- case FLUTTER: updateBeam(&Googelon, targets, temptarget->x, temptarget->z, tanklist, allTreesEverywherePtrs,
- numTreesEverywhere, &thaMonster);
-
- thaMonster.energyRemaining -= 0.15;
- break;
-
- default: showError("Bogus Monster! (Update Targets)");
- break;
- }
-
- temptarget->monster = thaMonster;
- }
- else
- {
- /**********************************************/
- /* deal with the computer controlled monsters */
- /**********************************************/
-
- if (thaMonster.monster == FLUTTER)
- {
- mRad = 1.2;
- mAng = 1.0;
- }
- else
- {
- mRad = 0.8;
- mAng = 0.8;
- }
-
- if (((thaMonster.monsterGo || thaMonster.monsterBack)) && (!thaMonster.monsterIsDead))
- {
- thaMonster.monsterMoving = 1;
-
- thaMonster.energyRemaining -= thaMonster.moveCost; /* takes energy to move, not to turn */
-
- if (thaMonster.monsterGo)
- mAngle = (thaMonster.headHorzRotate * BIG_DEG_TO_RAD);
- if (thaMonster.monsterBack)
- mAngle = (thaMonster.headHorzRotate + 1800) * BIG_DEG_TO_RAD;
-
-
-
- blocked = 0;
-
- if (thaMonster.monster != VAPOUR)
- {
- /****************************************************/
- /* cant move through trees until they are destroyed */
- /****************************************************/
-
- temptree = treelist->next;
- while ((temptree != NULL) && (!blocked))
- {
- ttree = *temptree;
-
- trad = sqrt((ttree.x - tx) * (ttree.x - tx) + (ttree.z - tz) * (ttree.z - tz));
-
- if (trad < mRad)
- {
- obsangle = computeAngle(ttree.z, tz, ttree.x, tx);
-
- if (obsangle < 0)
- obsangle += TWOPI;
-
- if ((fabs(mAngle + PI - obsangle) < mAng) || (fabs(mAngle - PI - obsangle) < mAng))
- {
- if (thaMonster.monster != FLUTTER)
- blocked = 1;
- else if ((buildingHeight(ttree.type, ttree.treeshape) > 0) ||
- ((ttree.type == 1) && (ttree.treeshape == 3) && (ttree.intact == 1)))
- blocked = 1;
- }
- }
-
- temptree = temptree->next;
- }
-
- /****************************************************/
- /* cant move through tanks until they are destroyed */
- /****************************************************/
-
- temptank = tanklist->next;
- while ((temptank != NULL) && !blocked)
- {
-
- trad = sqrt((temptank->x - tx) * (temptank->x - tx) + (temptank->z - tz) * (temptank->z - tz));
-
- if (trad < thaMonster.width)
- {
- obsangle = computeAngle(temptank->z, tz, temptank->x, tx);
-
- if (obsangle < 0)
- obsangle += TWOPI;
-
- if ((fabs(mAngle + PI - obsangle) < .75) || (fabs(mAngle - PI - obsangle) < .75))
- {
- if ((temptank->y <= thaMonster.height) && (temptank->y >= thaMonster.bottom))
- blocked = 1;
- if ((temptank->type == HERO) || (temptank->type == MECHAG))
- blocked = 1;
- }
- }
-
- temptank = temptank->next;
- }
- }
-
- /***********************************************************************************/
- /* cant move through other targets until they are destroyed or move out of the way */
- /***********************************************************************************/
-
- if (temptarget->monster.monster != VAPOUR)
- {
- temptarget2 = targets->next;
- while ((temptarget2 != NULL) && (!blocked))
- {
- if ((temptarget2 != temptarget) && (temptarget2->monster.monster != VAPOUR))
- {
- rad = sqrt((temptarget2->x - tx) * (temptarget2->x - tx) + (temptarget2->z - tz) * (temptarget2->z - tz));
-
- if (rad < mRad)
- {
- obsangle = computeAngle(temptarget2->z, tz, temptarget2->x, tx);
-
- if (obsangle < 0)
- obsangle += TWOPI;
-
- if ((fabs(mAngle + PI - obsangle) < mAng) || (fabs(mAngle - PI - obsangle) < mAng))
- blocked = 1;
- }
- }
- temptarget2 = temptarget2->next;
- }
-
- /**************************************/
- /* cant move through player's monster */
- /**************************************/
-
- rad = sqrt(tx * tx + tz * tz);
-
- if ((rad < mRad) && (Googelon.monster != VAPOUR))
- {
- obsangle = computeAngle(-temptarget->z, 0, -temptarget->x, 0);
-
- if (obsangle < 0)
- obsangle += TWOPI;
-
- if ((fabs(mAngle + PI - obsangle) < mAng) || (fabs(mAngle - PI - obsangle) < mAng))
- blocked = 1;
- }
- }
-
- if (!blocked)
- {
- temptarget->z += cos(mAngle) * thaMonster.speed;
- temptarget->x += sin(mAngle) * thaMonster.speed;
- }
- }
-
- /**********************************/
- /* update target Weapons */
- /**********************************/
-
- if (thaMonster.beamOn)
- switch (thaMonster.monster){
- case GOOGELON: updateBeam(&Googelon, targets, temptarget->x, temptarget->z, tanklist, allTreesEverywherePtrs,
- numTreesEverywhere, &thaMonster);
-
- thaMonster.energyRemaining -= 0.15;
- break;
-
- case TECHS: updateGun(temptarget->x, temptarget->z, thaMonster.headHorzRotate,
- thaMonster.headVertRotate, mainCounter, &(temptarget->monster));
- thaMonster.energyRemaining -= 0.09;
- break;
-
- case VAPOUR: updateVap(temptarget->x, temptarget->z, mainCounter, &(temptarget->monster));
- thaMonster.energyRemaining -= 0.1;
- break;
-
- case FLUTTER: updateBeam(&Googelon, targets, temptarget->x, temptarget->z, tanklist, allTreesEverywherePtrs,
- numTreesEverywhere, &thaMonster);
-
- thaMonster.energyRemaining -= 0.15;
- break;
-
- default: showError("Bogus Monster! (Update Targets)");
- break;
- }
-
- /********************************************/
- /* update the vapourness of a target vapour */
- /********************************************/
-
- if (thaMonster.monster == VAPOUR)
- updateVapourLook(thaMonster.a, thaMonster.monsterIsDead);
-
- /*****************/
- /* update energy */
- /*****************/
-
- if (thaMonster.energyRemaining > 0)
- {
- thaMonster.energyRemaining += thaMonster.regenRate;
-
- if (thaMonster.energyRemaining > MAXLIFE)
- thaMonster.energyRemaining = MAXLIFE;
-
- thaMonster.rot1 = cos(thaMonster.moveCount) * 0.02;
- thaMonster.rot2 = sin(thaMonster.moveCount) * 0.05;
- }
- else
- {
- updateDeadMonster(temptarget->x, temptarget->z, &thaMonster);
- }
-
- if (thaMonster.monsterMoving)
- thaMonster.moveCount += 1;
-
-
- temptarget->monster = thaMonster;
- }
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* update everything */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void doUpdate()
- {
- struct boom * tempboom;
- struct tree * temptree;
- struct tank * temptank;
- struct targetInfo * temptarget;
- struct targetInfo * temptarg;
- struct projectile * temp;
- struct tree ttree;
- float rad;
- float mAngle, obsangle;
- float xv, zv;
- float mRad, mAng;
- int blocked;
-
-
- /*************************************************/
- /* reclaim space from finished sounds */
- /*************************************************/
-
- if (!noSound)
- {
- flushSounds();
-
- if (getMusicOn())
- doSound(MUSIC);
- else
- soundKiller(MUSIC);
- }
-
- /*************************************************/
- /* add another monster if the time is right */
- /*************************************************/
-
- if ((!netUp) && (!client) && (!alone))
- {
- if (mode == DEMOMODE)
- {
- if ((mainCounter > 500) && ((mainCounter % 4000) == 1500))
- addRandomTarget();
- }
- else
- if ((mainCounter > 1000) && ((mainCounter % 9000) == 8000))
- addRandomTarget();
- }
-
- /*********************/
- /* add a new vehicle */
- /*********************/
-
- if (!client)
- {
- if (((mainCounter % arrivalTime) == 0) && !Googelon.monsterIsDead)
- {
- addNewTank(targets, 0, 0, -1, tanklist, treelist, mainCounter, firingDelay, &Googelon);
-
- if ((mode == DEMOMODE) && !(rand() % 4) && (Googelon.moveCount >= 150))
- view = (view + 1) % 3;
- }
- }
-
- /**********************************/
- /* monster on the move */
- /**********************************/
-
- if (Googelon.monster == FLUTTER)
- {
- mRad = 1.2;
- mAng = 1.0;
- }
- else
- {
- mRad = 0.8;
- mAng = 0.8;
- }
-
- if (Googelon.monsterGo || Googelon.monsterBack)
- {
- Googelon.monsterMoving = 1;
-
- Googelon.energyRemaining -= Googelon.moveCost; /* takes energy to move, not to turn */
-
- if (Googelon.monsterGo)
- mAngle = (Googelon.headHorzRotate * BIG_DEG_TO_RAD);
-
- if (Googelon.monsterBack)
- mAngle = (Googelon.headHorzRotate + 1800) * BIG_DEG_TO_RAD;
-
-
- blocked = 0;
-
- if (Googelon.monster != VAPOUR)
- {
- /****************************************************/
- /* cant move through trees until they are destroyed */
- /****************************************************/
-
- temptree = treelist->next;
- while ((temptree != NULL) && (!blocked))
- {
- ttree = *temptree;
-
- if (ttree.rad < mRad)
- {
- obsangle = ttree.theta;
- if (obsangle < 0)
- obsangle += TWOPI;
-
- if ((fabs(mAngle + PI - obsangle) < mAng) || (fabs(mAngle - PI - obsangle) < mAng))
- {
- if (Googelon.monster != FLUTTER)
- blocked = 1;
- else if ((buildingHeight(ttree.type, ttree.treeshape) > 0) ||
- ((ttree.type == 1) && (ttree.treeshape == 3) && (ttree.intact == 1)))
- blocked = 1;
- }
- }
-
- temptree = temptree->next;
- }
-
- /****************************************************/
- /* cant move through tanks until they are destroyed */
- /****************************************************/
-
- temptank = tanklist->next;
- while ((temptank != NULL) && !blocked)
- {
- if (temptank->rad < Googelon.width)
- {
- obsangle = temptank->theta;
- if (obsangle < 0)
- obsangle += TWOPI;
-
- if ((fabs(mAngle + PI - obsangle) < .75) || (fabs(mAngle - PI - obsangle) < .75))
- {
- if ((temptank->y <= Googelon.height) && (temptank->y >= Googelon.bottom))
- blocked = 1;
- if ((temptank->type == HERO) || (temptank->type == MECHAG))
- blocked = 1;
- }
- }
- temptank = temptank->next;
- }
-
- /***********************************************************************************/
- /* cant move through other targets until they are destroyed or move out of the way */
- /***********************************************************************************/
-
- temptarget = targets->next;
- while ((temptarget != NULL) && (!blocked))
- {
- rad = sqrt(temptarget->x * temptarget->x + temptarget->z * temptarget->z);
-
- if ((rad < mRad) && (temptarget->monster.monster != VAPOUR) && (temptarget->monster.monsterIsDead != 1))
- {
- obsangle = computeAngle(temptarget->z, 0, temptarget->x, 0);
-
- if (obsangle < 0)
- obsangle += TWOPI;
-
- if ((fabs(mAngle + PI - obsangle) < mAng) || (fabs(mAngle - PI - obsangle) < mAng))
- blocked = 1;
- }
-
- temptarget = temptarget->next;
- }
- }
-
- /***************************************/
- /* update position of everything else */
- /***************************************/
-
- if (!blocked)
- {
- zv = cos(mAngle) * Googelon.speed;
- xv = sin(mAngle) * Googelon.speed;
-
- for(temptank = tanklist->next;temptank != NULL;temptank = temptank->next)
- {
- temptank->x -= xv;
- temptank->z -= zv;
- }
- for(tempboom = projectboom->next;tempboom != NULL;tempboom = tempboom->next)
- {
- tempboom->x -= xv;
- tempboom->z -= zv;
- }
- for(temp = projectFlight->next;temp != NULL;temp = temp->next)
- {
- temp->x -= xv;
- temp->z -= zv;
- }
- for(temptank = slaglist->next;temptank != NULL;temptank = temptank->next)
- {
- temptank->x -= xv;
- temptank->z -= zv;
- }
- for(temptree = treelist->next;temptree != NULL;temptree = temptree->next)
- {
- temptree->x -= xv;
- temptree->z -= zv;
- }
- for(temptarget = targets->next;temptarget != NULL;temptarget = temptarget->next)
- {
- temptarget->x -= xv;
- temptarget->z -= zv;
-
- temptarget->net_x -= xv;
- temptarget->net_z -= zv;
- }
-
- globalxshift -= xv;
- globalzshift -= zv;
- }
- }
-
- /**********************/
- /* update structures */
- /**********************/
-
- if (treelist->next != NULL)
- updatetrees(treelist, itsChristmas);
-
- /**********************************/
- /* isolate the trees on the plane */
- /* must come after update trees */
- /**********************************/
-
- numTreesOnPlane = 0;
- numTreesEverywhere = 0;
-
- for(temptree = treelist->next; temptree != NULL; temptree = temptree->next)
- {
- allTreesEverywhere[numTreesEverywhere] = *temptree;
- allTreesEverywherePtrs[numTreesEverywhere] = temptree;
- numTreesEverywhere += 1;
-
- if ((fabs(temptree->x) <= PLANESIZE) && (fabs(temptree->z) <= PLANESIZE))
- {
- allTreesOnPlane[numTreesOnPlane] = *temptree;
- allTreesOnPlanePtrs[numTreesOnPlane] = temptree;
- numTreesOnPlane += 1;
-
- if (numTreesOnPlane >= MAXTREESONPLANE)
- {
- showError("Too many trees on the plane");
- numTreesOnPlane -= 1;
- }
- }
- }
-
- /****************************/
- /* update all the targets */
- /****************************/
-
- if (targets->next != NULL)
- updateTargets();
-
-
- /************************/
- /* update the vehicles */
- /************************/
-
- if (tanklist->next != NULL)
- updateTanks(tanklist, Googelon.width, Googelon.height, Googelon.bottom,
- Googelon.monsterIsDead, Googelon.monster, slaglist, accuracy,
- firingDelay, mainCounter, &Googelon, targets);
-
-
- /****************************/
- /* update the slagging tank */
- /****************************/
-
- if (slaglist->next != NULL)
- updateSlagTanks(slaglist);
-
-
- /**************************/
- /* update the projectiles */
- /**************************/
-
- quickTanks();
-
- if (projectFlight->next != NULL)
- updateProjectiles();
-
-
- /**********************************/
- /* update monster Weapons */
- /**********************************/
-
- if (Googelon.beamOn)
- {
-
- #ifndef MACVERSION
- turnBeamOnSinceLast();
- #endif
- switch (Googelon.monster)
- {
- case GOOGELON: updateBeam(&Googelon, targets, 0, 0, tanklist, allTreesOnPlanePtrs, numTreesOnPlane, &Googelon);
- Googelon.energyRemaining -= 0.15;
- break;
-
- case TECHS: updateGun(0, 0, Googelon.headHorzRotate, Googelon.headVertRotate, mainCounter, &Googelon);
- Googelon.energyRemaining -= 0.09;
- break;
-
- case VAPOUR: updateVap(0, 0, mainCounter, &Googelon);
- Googelon.energyRemaining -= 0.1;
- break;
-
- case FLUTTER: updateBeam(&Googelon, targets,0, 0, tanklist, allTreesOnPlanePtrs, numTreesOnPlane, &Googelon);
- Googelon.energyRemaining -= 0.15;
- break;
-
- default: showError("Bogus Monster! (doUpdate)");
- break;
- }
- }
-
- /*************************/
- /* update the explosions */
- /*************************/
-
- if (projectboom->next != NULL)
- updateBooms(projectboom, tanklist);
-
-
- /***********************/
- /* update the monster */
- /***********************/
-
- if (!Googelon.beamOn)
- soundKiller(MONSTERBEAM);
-
-
- /*********************************************************************/
- /* update the Vapour's particles (must do for all! re menu monsters */
- /*********************************************************************/
-
- updateVapourLook(Googelon.a, Googelon.monsterIsDead);
-
-
- /****************************/
- /* update monster's energy */
- /****************************/
-
- if (Googelon.energyRemaining > 0)
- {
- Googelon.energyRemaining += Googelon.regenRate;
-
- if (Googelon.energyRemaining > MAXLIFE)
- Googelon.energyRemaining = MAXLIFE;
-
- Googelon.rot1 = cos(Googelon.moveCount) * 0.02;
- Googelon.rot2 = sin(Googelon.moveCount) * 0.05;
- }
- else
- {
- updateDeadMonster(0, 0, &Googelon);
- }
-
- if (Googelon.monsterMoving)
- Googelon.moveCount += 1;
-
- /*************************************/
- /* update the high-score list */
- /*************************************/
-
- if (Googelon.monsterIsDead && (Googelon.deadCount == 1))
- updateScores(scorefullPath, Googelon.monster, Googelon.monsterScore, mode, playerName);
-
- /*********************************/
- /* deal with dead targets */
- /*********************************/
-
- temptarget = targets;
- while(temptarget->next != NULL)
- {
- {
- if (temptarget->next->monster.timeDead > 250)
- {
- for(tboom=projectboom->next; tboom != NULL; tboom=tboom->next)
- {
- if (tboom->mine == &(temptarget->next->monster))
- tboom->mine = NULL;
- }
-
- for(tproj=projectFlight->next; tproj != NULL; tproj=tproj->next)
- {
- if (tproj->mine == &(temptarget->next->monster))
- tproj->mine = NULL;
- }
-
- temptarg = temptarget->next;
- temptarget->next = temptarget->next->next;
-
- if ((temptarg->monster.monster == FLUTTER) ||(temptarg->monster.monster == GOOGELON))
- {
- addProjectile( temptarg->x-0.2, PLANEY+0.25, temptarg->z+0.2, 3, 0, -0.003, 0, 10000, NULL);
- addProjectile( temptarg->x+0.2, PLANEY+0.25, temptarg->z+0.2, 3, 0, -0.003, 0, 10000, NULL);
- addProjectile( temptarg->x+0.2, PLANEY+0.25, temptarg->z-0.2, 3, 0, -0.003, 0, 10000, NULL);
- addProjectile( temptarg->x-0.2, PLANEY+0.25, temptarg->z-0.2, 3, 0, -0.003, 0, 10000, NULL);
- }
-
- afree(temptarg, arena);
- }
- else
- temptarget = temptarget->next;
- }
- }
-
- if ((mode == DEMOMODE) && (Googelon.timeDead > 400))
- {
- Googelon.monster = (Googelon.monster + 1) % 4;
- setPlayConditions();
- }
-
- /*************************************/
- /* vehicles arrive faster later on */
- /*************************************/
-
- arrivalTime = (int) (ARRIVALRATE - (mainCounter * 0.0005));
- if (arrivalTime < 20)
- arrivalTime = 20;
-
- /*************************************/
- /* vehicles more accurate later on */
- /*************************************/
-
- accuracy = (STARTACCURACY + (mainCounter * 0.002));
- if (accuracy > 500)
- accuracy = 500;
-
- /*************************************/
- /* vehicles fire faster later on */
- /*************************************/
-
- firingDelay = (int) (STARTFIRINGDELAY - (mainCounter * 0.0005));
- if (firingDelay < 43)
- firingDelay = 43;
-
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* view the scene from the monster's point of view */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void goToMonsterView(int eyeball)
- {
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(90, 1, 0.1, 15);
- glMatrixMode(GL_MODELVIEW);
-
- switch(eyeball){
- case 2: glCallList(monsterLookat);
- break;
-
- case 0: gluLookAt( 0.015, PLANEY + 2.4, 0.1, 0.015, PLANEY, 1, 0,1, 0);
- break;
-
- case 1: gluLookAt( -0.015, PLANEY + 2.4, 0.1, -0.015, PLANEY, 1, 0,1, 0);
- break;
-
- }
-
- if (lod >= 2)
- {
- glFogi(GL_FOG_START, MONSTERFOGSTART);
- glFogi(GL_FOG_END, MONSTERFOGEND);
-
- glEnable(GL_FOG);
- }
-
- yrot = - (GLfloat) Googelon.headHorzRotate;
- xrot = 360;
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* view teh scene from the most recently added military vehicle */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void goToArmyView(int eyeball)
- {
- /*look throgh 0,0 to opposite side and assign the opposite to the
- OTHER one making 2 parallel lines! */
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(60, 1, 0.1, 20);
- glMatrixMode(GL_MODELVIEW);
-
- switch(eyeball){
- case 2: gluLookAt(lastTankRad * sin(lastTankTheta), lastTankY,
- lastTankRad*cos(lastTankTheta), 0, lastTankY, 0, 0,1,0);
- break;
-
- case 0: gluLookAt(lastTankRad * sin(lastTankTheta + 0.002),
- lastTankY, lastTankRad * cos(lastTankTheta + 0.002),
- -lastTankRad * sin(lastTankTheta-0.002), lastTankY,
- -lastTankRad * cos(lastTankTheta-0.002), 0,1,0);
- break;
-
- case 1: gluLookAt(lastTankRad * sin(lastTankTheta - 0.002),
- lastTankY, lastTankRad * cos(lastTankTheta - 0.002),
- -lastTankRad*sin(lastTankTheta+0.002), lastTankY,
- -lastTankRad * cos(lastTankTheta+0.002), 0,1,0);
- break;
- }
-
- if (lod >= 2)
- {
- glFogi(GL_FOG_START, ARMYFOGSTART);
- glFogi(GL_FOG_END, ARMYFOGEND);
- glEnable(GL_FOG);
- }
-
- xrot = yrot = 0;
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* view the scene from above */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void goToMapView()
- {
- /* used to get overhead map of the town */
- /* also set plane size to 40 */
- /* and eliminate prepositioned vehicles */
- /* and hide motion dots */
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(mapHeight*viewW/viewH, -mapHeight*viewW/viewH, mapHeight,
- -mapHeight, 0.1, 50);
- glMatrixMode(GL_MODELVIEW);
-
- gluLookAt(0, mapHeight, 0, 0, PLANEY, 0, 0, 0, 1);
- xrot = yrot = 0;
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* view the scene from omniscient 3rd person */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void goToOverView(int eyeball)
- {
- view = OMNISCIENTVIEW;
-
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(60, 1, 0.1, 25);
- glMatrixMode(GL_MODELVIEW);
-
- switch(eyeball){
- case 2: glCallList(overviewLookat);
- break;
-
- case 0: gluLookAt( 0.05, 0, 9, 0.05, 0, 0, 0,1,0);
- break;
-
- case 1: gluLookAt(-0.05, 0, 9, -0.05, 0, 0, 0,1,0);
- break;
- }
-
- if (lod >= 2)
- {
- glFogi(GL_FOG_START, OVERVIEWFOGSTART);
- glFogi(GL_FOG_END, OVERVIEWFOGEND);
- glEnable(GL_FOG);
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* draw a given monster at a given location */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void drawAMonster(float x, struct monsterInfo monster, float z,
- int isTarget, int view)
- {
-
- if ((fabs(x) <= PLANESIZE) && (fabs(z) <= PLANESIZE))
- {
- glPushMatrix();
- glTranslatef(x, 0, z);
- switch(monster.monster){
- case GOOGELON: if (monster.energyRemaining <= 0)
- {
- glTranslatef(0, -monster.deadCount * 0.015, 0);
- glRotatef(-monster.deadCount * 2, 1,0,0);
- glRotatef(-monster.deadCount * 2, 0,1,0);
- }
- if ((!isTarget) && (view == MONSTERVIEW))
- drawSimpleMonster(monster, mainCounter, itsChristmas, lod);
- else
- drawMonster(monster, mainCounter, itsChristmas, lod);
- break;
-
- case VAPOUR: drawVapour(monster, itsChristmas, lod);
- break;
-
- case TECHS: if (monster.energyRemaining <= 0)
- {
- glTranslatef(0, -monster.deadCount * 0.015, 0);
- glRotatef(-monster.deadCount * 2, 1,0,0);
- }
- if ((!isTarget) && (view == MONSTERVIEW))
- drawSimpleTechs(monster,lod);
- else
- drawTechs(monster,lod);
- break;
-
- case FLUTTER: if (monster.energyRemaining <= 0)
- {
- glTranslatef(0, -monster.deadCount * 0.025, 0);
- glRotatef(-monster.deadCount * 2.5, 0,1,0);
- }
- if (isTarget)
- drawFlutter(monster, mainCounter, itsChristmas,
- offsetX, OMNISCIENTVIEW, lod);
- else
- drawFlutter(monster, mainCounter, itsChristmas,
- offsetX, view, lod);
-
- break;
- }
- glPopMatrix();
- }
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* draw everything */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void doDrawing (int eyeball)
- {
- GLenum glErrorVal;
- GLint tmp[4];
- struct targetInfo * temptarget;
-
- /***********************/
- /* check for GL errors */
- /***********************/
-
- /* mac 68K version giving a spurious error mesage here */
-
- glErrorVal = glGetError();
- #ifndef MACVERSION
- if (glErrorVal != GL_NO_ERROR)
- showError((char *) gluErrorString(glErrorVal));
- #endif
-
- /* if line widths are integral Mesa chokes in a large window */
-
- if (lod > -1)
- glLineWidth(2.01);
- else
- glLineWidth(1.01);
-
- if (lod >= 2)
- glShadeModel(GL_SMOOTH);
- else
- glShadeModel(GL_FLAT);
-
-
- /****************************************************************/
- /* MUST enable dithering or the 8-bit machines look REALLY ugly */
- /****************************************************************/
-
- glEnable(GL_DITHER);
-
-
- glPushMatrix();
-
- /**********************************/
- /* setting viewing location */
- /**********************************/
-
- if (view == MONSTERVIEW)
- goToMonsterView(eyeball);
- else if ((view == ARMYVIEW) && (lastTankY > NOTANKONPLANE))
- goToArmyView(eyeball);
- else if (view == MAPVIEW)
- goToMapView();
- else /*view == OMNISCIENTVIEW */
- goToOverView(eyeball);
-
- /***********************************/
- /* rotate and draw the battlefield */
- /***********************************/
-
- if (xrot != 0)
- glRotatef(0.1 * xrot, 1,0,0);
-
- if (yrot != 0)
- glRotatef(0.1 * yrot, 0,1,0);
-
- glDisable(GL_DEPTH_TEST);
-
- drawBattlefield(roadSystem, globalxshift, globalzshift, lod,
- itsChristmas, view);
-
- if (lod != -1)
- glEnable(GL_DEPTH_TEST);
-
- /**********************************/
- /* draw the slagging vehicles */
- /**********************************/
-
- if (slaglist->next != NULL)
- drawSlagTanks(slaglist, mainCounter, lod);
-
-
- /******************************************************/
- /* draw the vehicles */
- /* must come before draw structures for hero entrance */
- /******************************************************/
-
- if (tanklist->next != NULL)
- drawTanks(tanklist, mainCounter, Googelon, targets, lod,
- view, viewW);
-
-
-
- /**********************************/
- /* draw all projectiles in flight */
- /**********************************/
-
- if (projectFlight->next != NULL)
- drawProjectiles(projectFlight, mainCounter, fires,
- flameCount, itsChristmas,lod);
-
-
-
- /********************/
- /* draw structures */
- /********************/
-
- if (treelist->next != NULL)
- if (view == MAPVIEW)
- drawtrees(allTreesEverywhere, numTreesEverywhere, mainCounter,
- lod, itsChristmas, view);
- else
- drawtrees(allTreesOnPlane, numTreesOnPlane, mainCounter,
- lod, itsChristmas, view);
-
-
-
- /**********************************/
- /* draw monsterBeam */
- /**********************************/
-
- if ((Googelon.beamOn) && ((Googelon.monster == GOOGELON) ||
- (Googelon.monster == FLUTTER)))
- drawBeam(0, 0, Googelon.headHorzRotate, Googelon.headVertRotate,
- Googelon.monster, lod);
-
- for (temptarget = targets->next;temptarget != NULL;temptarget = temptarget->next)
- if ((temptarget->monster.beamOn) &&
- ((temptarget->monster.monster == GOOGELON) ||
- (temptarget->monster.monster == FLUTTER)))
- drawBeam(temptarget->x, temptarget->z,
- temptarget->monster.headHorzRotate,
- temptarget->monster.headVertRotate,
- temptarget->monster.monster, lod);
-
-
-
- /*************************************************/
- /* draw explosions to be seen through the VAPOUR */
- /*************************************************/
- /*I suppose technically if ANY monster on the field is the vapour this
- * should be done but that may be too costly
- */
-
- if ((Googelon.monster == VAPOUR) && (projectboom->next != NULL))
- {
- if (lod == -1)
- {
- glPushAttrib(GL_POLYGON_BIT);
- glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
- drawBooms(projectboom, lod);
- glPopAttrib();
- }
- else
- drawBooms(projectboom, lod);
- }
-
-
-
- /**********************************/
- /* draw the targets */
- /**********************************/
-
- for(temptarget = targets->next;temptarget != NULL;temptarget = temptarget->next)
- drawAMonster(temptarget->x, temptarget->monster, temptarget->z, 1,view);
-
-
- /**********************************/
- /* draw the player's monster */
- /**********************************/
-
- drawAMonster(0, Googelon, 0, 0,view);
-
- /**********************************/
- /* draw explosions */
- /* */
- /* explosions must be last so */
- /* other things can be seen */
- /* throught them */
- /**********************************/
-
- if (projectboom->next != NULL)
- {
- if (lod == -1)
- {
- glPushAttrib(GL_POLYGON_BIT);
- glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
- drawBooms(projectboom, lod);
- glPopAttrib();
- }
- else
- drawBooms(projectboom, lod);
- }
-
- glDisable(GL_FOG);
-
- glPopMatrix();
-
- if (!backdrop)
- {
- glGetIntegerv(GL_VIEWPORT, tmp);
- viewL = tmp[0];
- viewR = viewL+tmp[2] - 1;
-
- glPushMatrix();
-
- /**********************************/
- /* print the overlays */
- /**********************************/
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(60, 1, 0.1, 20);
- glMatrixMode(GL_MODELVIEW);
-
- switch(eyeball){
- case 2: glCallList(overviewLookat);
- break;
- case 0: gluLookAt( 0.065, 0, 9, 0.065, 0, 0, 0,1,0);
- break;
- case 1: gluLookAt(-0.065, 0, 9, -0.065, 0, 0, 0,1,0);
- break;
- }
-
- textLineWidth = (viewR-viewL) / 300.0;
- if (textLineWidth < 1)
- textLineWidth = 1.01;
-
- if (lod == -1)
- textLineWidth = 1.01;
-
- /* if line widths are integral Mesa chokes in a large window */
- glLineWidth(textLineWidth);
-
- /* showText(Googelon.energyRemaining, Googelon.monsterScore,
- (long) (viewR-viewL), paused); */
-
- showText(targets, Googelon.energyRemaining, Googelon.monsterScore,
- showframes, paused, pointerGrab);
-
- if (mode == DEMOMODE)
- {
- if (!(Googelon.timeDead > 100) && !showOptions)
- if (Googelon.moveCount < 150)
- showScores(itsChristmas, G, V, T, F, Googelon, mainCounter, offsetX, lod);
- else
- showText2((long) (viewR-viewL), getSoundOn(), noSound, getMusicOn(),
- mode3D, no3D, lod, paused, itsChristmas, pointerGrab);
-
-
- showText3(lod);
-
- if (showOptions)
- doOptions(Googelon, (long) (viewR-viewL), mainCounter, itsChristmas, offsetX, lod);
- else
- showText4();
-
- if ((Googelon.timeDead > 100) && !showOptions)
- doSummary(Googelon.monster, Googelon.timeDead,
- (long) (viewR-viewL), killtanks, killmtanks,
- killhelos, killCHHs, killmechags, killheros,
- killplanes, killlaunchers, killfighters,
- mainCounter, lod, moreThanOne);
- }
-
- glPopMatrix();
- }
-
- /* part of test to see if single buffering can be used in vector mode
- if (lod > -1 )
- */
-
- tkSwapBuffers();
-
- #ifdef MACVERSION
-
- drawGrow();
-
- #endif
- }
-
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* computer controlled monster for demo-mode */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- struct monsterInfo autopilot(float centerX, float centerZ, struct monsterInfo thaMonster)
- {
- struct tank * ttank;
- struct tree * ttree;
-
- struct enemy et, el, em, eh, ec, eg, ehe, ep, eb, ef, eall, einside;
-
- float alphaBig;
- float modHead;
- float y, ang, r, modR;
- int speed, speed2;
- int t;
- float rad;
- float tx, tz;
- float zdiff;
- float xdiff;
-
- t = -1;
-
- et.r = el.r = em.r = eh.r = ec.r = eg.r =
- ehe.r = ep.r = eb.r = ef.r = eall.r = BIGNUM;
-
- /*************************************/
- /* find nearest building to destroy */
- /*************************************/
-
- for(ttree = treelist->next; ttree != NULL; ttree = ttree->next)
- if ((ttree->type == 1) && (ttree->intact == 1))
- {
- zdiff = ttree->z-centerZ;
- xdiff = ttree->x-centerX;
-
- rad = sqrt(xdiff * xdiff + zdiff * zdiff);
-
- if (rad < eb.r)
- {
- eb.r = rad;
- eb.y = ttree->y;
- eb.ang = computeAngle(zdiff, 0, xdiff, 0);
- }
- }
-
- /*********************************/
- /* find nearest military threat */
- /*********************************/
-
- eall = eb;
- einside = eb;
-
- for(ttank = tanklist->next; ttank != NULL; ttank = ttank->next)
- {
- tx = ttank->x;
- tz = ttank->z;
- rad = sqrt((tx-centerX) * (tx-centerX) + (tz-centerZ) * (tz-centerZ));
-
- if (rad < eall.r)
- {
- eall.r = rad;
- eall.y = ttank->y;
- eall.ang = computeAngle(tz, centerZ, tx, centerX);
- }
-
- if ((rad < einside.r) && (fabs(tx) < fabs(centerX)) && (fabs(tz) < fabs(centerZ)))
- {
- einside.r = rad;
- einside.y = ttank->y;
- einside.ang = computeAngle(tz, centerZ, tx, centerX);
- }
-
- if (rad <= PLANESIZE)
- {
-
- switch(ttank->type){
- case TANK : if (rad < et.r)
- {
- et.r = rad;
- et.y = ttank->y;
- et.ang = computeAngle(tz, centerZ, tx, centerX);
- }
- break;
-
- case LAUNCHER : if (rad < el.r)
- {
- el.r = rad;
- el.y = ttank->y;
- el.ang = computeAngle(tz, centerZ, tx, centerX);
- }
- break;
-
- case MASERTANK : if (rad < em.r)
- {
- em.r = rad;
- em.y = ttank->y;
- em.ang = computeAngle(tz, centerZ, tx, centerX);
- }
- break;
-
- case HELO : if (rad < eh.r)
- {
- eh.r = rad;
- eh.y = ttank->y;
- eh.ang = computeAngle(tz, centerZ, tx, centerX);
- }
- break;
-
- case CHH : if (rad < ec.r)
- {
- ec.r = rad;
- ec.y = ttank->y;
- ec.ang = computeAngle(tz, centerZ, tx, centerX);
- }
- break;
-
- case MECHAG : if (rad < eg.r)
- {
- eg.r = rad;
- eg.y = ttank->y + 0.5;
- eg.ang = computeAngle(tz, centerZ, tx, centerX);
- }
- break;
-
- case HERO : if (rad < ehe.r)
- {
- ehe.r = rad;
- ehe.y = ttank->y + 0.5;
- ehe.ang = computeAngle(tz, centerZ, tx, centerX);
- }
- break;
-
- case AIRPLANE : if (rad < ep.r)
- {
- ep.r = rad;
- ep.y = ttank->y + 0.5;
- ep.ang = computeAngle(tz, centerZ, tx, centerX);
- }
- break;
-
- case FIGHTER : if (rad < ef.r)
- {
- ef.r = rad;
- ef.y = ttank->y + 0.5;
- ef.ang = computeAngle(tz, centerZ, tx, centerX);
- }
- break;
-
- default: showError("Bogus Vehicle! (autopilot)");
- break;
- }
-
- }
-
- }
-
- /****************************/
- /* choose target to attack */
- /****************************/
-
- if (ehe.r != BIGNUM)
- {
- r = ehe.r;
- y = ehe.y;
- ang = ehe.ang;
- t = HERO;
- }
- else if (eg.r != BIGNUM)
- {
- r = eg.r;
- y = eg.y;
- ang = eg.ang;
- t = MECHAG;
- }
- else if (ec.r != BIGNUM)
- {
- r = ec.r;
- y = ec.y;
- ang = ec.ang;
- t = CHH;
- }
- else if (em.r != BIGNUM)
- {
- r = em.r;
- y = em.y;
- ang = em.ang;
- t = MASERTANK;
- }
- else if (el.r != BIGNUM)
- {
- r = el.r;
- y = el.y;
- ang = el.ang;
- t = LAUNCHER;
- }
- else if ((eb.r < et.r) && (eb.r < eh.r))
- {
- r = eb.r;
- y = eb.y + 0.5;
- ang = eb.ang;
- t = HERO; /* building */
- }
- else if (eh.r < et.r)
- {
- r = eh.r;
- y = eh.y;
- ang = eh.ang;
- t = HELO;
- }
- else if ((ep.r < et.r) && (et.r != BIGNUM))
- {
- r = ep.r;
- y = ep.y;
- ang = ep.ang;
- t = AIRPLANE;
- }
- else if ((ef.r < et.r) && (et.r != BIGNUM))
- {
- r = ef.r;
- y = ef.y;
- ang = ef.ang;
- t = FIGHTER;
- }
- else if (et.r < BIGNUM)
- {
- r = et.r;
- y = et.y;
- ang = et.ang;
- t = TANK;
- }
- else if (einside.r < BIGNUM)
- {
- r = einside.r;
- y = einside.y;
- ang = einside.ang;
- t = HERO;
- }
- else
- {
- r = eall.r;
- y = eall.y;
- ang = eall.ang;
- t = HERO;
- }
-
- /*********************/
- /* move the monster */
- /*********************/
-
- if (ang < 0)
- ang += TWOPI;
-
- modHead = (thaMonster.headHorzRotate+1800);
- if (modHead > 3600)
- modHead -= 3600;
-
- speed = (int) (ang * RAD_TO_BIG_DEG - modHead);
- if (speed > 1800)
- speed -= 3600;
- else if (speed < - 1800)
- speed += 3600;
-
- speed = speed / 15;
- if (speed > 0.75 * thaMonster.xspeed)
- speed = (int) (0.75 * thaMonster.xspeed);
- if (speed < -0.75 * thaMonster.xspeed)
- speed = (int) (-0.75 * thaMonster.xspeed);
-
- thaMonster.headHorzRotate += speed;
- offsetX = 0.8*offsetX - 0.2*(speed * 0.05); /* used to bank flutter in demo mode*/
-
- if ((thaMonster.energyRemaining > 15) && (fabs(speed) < 6) && (r < 3.5))
- thaMonster.beamOn = 1;
-
- switch(thaMonster.monster){
- case GOOGELON:
- case TECHS:
- if ((thaMonster.energyRemaining > 5) && (t != -1) && (t != HERO) &&
- (t != MECHAG) && ((fabs(speed) < 3) || (r < 1)))
- thaMonster.monsterGo = 1;
-
- else if (((t == MECHAG) || (t == HERO)) && (fabs(speed) < 5) && (r > 3))
- thaMonster.monsterGo = 1;
-
- else if (((t == MECHAG) || (t == HERO)) && (fabs(speed) < 5) && (r < .75))
- thaMonster.monsterBack = 1;
- break;
-
- case VAPOUR:
- if (((t == MECHAG) || (t == CHH) || (t == HERO)) && (r < 0.2))
- /*stay put on top of the enemy*/;
-
- else if ((thaMonster.energyRemaining > 5) && ((fabs(speed) < 10) || (r < 4)))
- thaMonster.monsterGo = 1;
- break;
-
- case FLUTTER:
- if ((thaMonster.energyRemaining > 5) && (t != -1) && (t != HERO) &&
- (t != MECHAG) && ((fabs(speed) < 3) || (r < 1)))
- thaMonster.monsterGo = 1;
- else if (((t == MECHAG) || (t == HERO)) && (fabs(speed) < 5) && (r > 3))
- thaMonster.monsterGo = 1;
- else if (((t == MECHAG) || (t == HERO)) && (fabs(speed) < 5) && (r < .75))
- thaMonster.monsterBack = 1;
- else if (!(((t == MECHAG) || (t == HERO)) && (fabs(speed) < 5) && (r < 1)))
- thaMonster.monsterGo = 1;
- break;
- }
-
- /************************/
- /* tilt monster's head */
- /************************/
-
- y = thaMonster.height - 0.1 - y;
-
- if (thaMonster.monsterGo)
- modR = r - 1.3;
- else
- modR = r - 0.6;
-
- if (modR <= 0)
- modR = NEARZERO;
-
- alphaBig = atan(y / modR) * RAD_TO_BIG_DEG;
-
- speed2 = (int) (fabs(alphaBig - thaMonster.headVertRotate))/15;
-
- if (alphaBig > thaMonster.headVertRotate)
- thaMonster.headVertRotate += speed2;
- else
- thaMonster.headVertRotate -= speed2;
-
- thaMonster.monsterMoving = 1;
-
- return(thaMonster);
- }
-
- /**********************************/
-
- void reshape( int width, int height )
- {
- viewW = width;
- viewH = height;
- glViewport(0, 0, width, height);
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* doDisplay */
- /* */
- /* draw everything */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- static void doDisplay(void)
- {
-
- /* part of test to see if single buffering can be used in vector mode
- if (lod == -1)
- glDrawBuffer(GL_FRONT);
- else
- glDrawBuffer(GL_BACK);
- */
-
- if (!mode3D)
- {
- /**********************************/
- /* draw in mono */
- /**********************************/
-
- if (lod == -1)
- glClear(GL_COLOR_BUFFER_BIT);
- else
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
-
- doDrawing(2);
- }
- else
- {
- short Height3d, Width3d;
-
- /**********************************/
- /* draw in stereo */
- /**********************************/
-
- if (doBigClear)
- {
- glViewport(0, 0, XMAXSCREEN+1, YMAXSCREEN+1);
- glScissor(0, 0, XMAXSCREEN+1, YMAXSCREEN+1);
-
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
- doBigClear -= 1;
- }
-
- Height3d = (short) windowTall/4;
- Width3d = (short) windowWide/2;
-
- glViewport((short) (XMAXSCREEN/2 - Width3d),
- (short) (YMAXSTEREO/2 - Height3d),
- ( (short) (XMAXSCREEN/2 + Width3d))-((short) (XMAXSCREEN/2 - Width3d))+1,
- ( (short) (YMAXSTEREO/2 + Height3d))-( (short) (YMAXSTEREO/2 - Height3d))+1);
-
- glScissor((short) (XMAXSCREEN/2 - Width3d), (short) (YMAXSTEREO/2 - Height3d),
- ( (short) (XMAXSCREEN/2 + Width3d))-((short) (XMAXSCREEN/2 - Width3d))+1,
- ( (short) (YMAXSTEREO/2 + Height3d))-( (short) (YMAXSTEREO/2 - Height3d))+1);
-
- glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
-
- doDrawing(0);
-
- glViewport((short) (XMAXSCREEN/2 - Width3d),
- (short) (YOFFSET+YMAXSTEREO/2 - Height3d),
- ( (short) (XMAXSCREEN/2 + Width3d))-((short) (XMAXSCREEN/2 - Width3d))+1,
- ((short) (YOFFSET+YMAXSTEREO/2 + Height3d))-( (short) (YOFFSET+YMAXSTEREO/2 - Height3d))+1);
-
- glScissor((short) (XMAXSCREEN/2 - Width3d), (short) (YOFFSET+YMAXSTEREO/2 - Height3d),
- ( (short) (XMAXSCREEN/2 + Width3d))-((short) (XMAXSCREEN/2 - Width3d))+1,
- ((short) (YOFFSET+YMAXSTEREO/2 + Height3d))-( (short) (YOFFSET+YMAXSTEREO/2 - Height3d))+1);
-
- glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
-
- doDrawing(1);
- }
- }
-
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* id */
- /* */
- /* this is the idle function for the tk code. This is called if */
- /* there are no interrupts to process. This computes the status */
- /* for the next frame and then draws the next frame */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- void id()
- {
- struct tank * ttank;
- struct targetInfo * temptarget;
-
- #ifdef MACVERSION
- if (mode == DEMOMODE)
- disableViewMenu();
- else
- enableViewMenu();
- #endif
-
- if (targets->next != NULL)
- {
- for(temptarget = targets->next; temptarget != NULL; temptarget = temptarget->next)
- {
- temptarget->monster.monsterMoving = 0;
- temptarget->monster.monsterGo = 0;
- temptarget->monster.monsterBack = 0;
-
- temptarget->monster.beamOn = 0;
- }
- }
-
- if (mode == DEMOMODE)
- {
- Googelon.beamOn = 0;
- }
-
- Googelon.monsterMoving = 0;
-
- if (Gturn)
- Googelon.monsterMoving = 1;
-
- checkMouse();
-
- /**************************************/
- /* update the frames / second counter */
- /**************************************/
-
- now = time(NULL);
- if (now != beg)
- {
- showframes = frames;
- frames = 0;
- beg = now;
- }
- frames += 1;
-
-
- totalCounter += 1;
-
- if (!paused)
- mainCounter += 1;
-
-
- if (Googelon.monsterIsDead)
- mode = DEMOMODE;
-
- oldview = view;
-
- if (view == MONSTERVIEW) /* must be before view change!!!!*/
- yrot = (GLfloat) -Googelon.headHorzRotate;
- else if (view == OMNISCIENTVIEW)
- {
- ysaverot = yrot;
- xsaverot = xrot;
- }
-
- if ((mode == DEMOMODE) && !Googelon.monsterIsDead && !paused)
- Googelon = autopilot(0, 0, Googelon);
-
-
- for(temptarget = targets->next; temptarget != NULL; temptarget = temptarget->next)
- temptarget->monster = autopilot(temptarget->x, temptarget->z, temptarget->monster);
-
-
- /**********************************/
- /* update everything */
- /**********************************/
-
- #ifndef MACVERSION
- if (netUp)
- processNetwork(now, mainCounter, totalCounter, treelist,
- tanklist, arena, Googelon, buildingBoomSoFarCounter,
- buildingBoomThisFrameCounter, buildingBoomSoFar,
- buildingBoomThisFrame);
-
- if (client)
- processClient(now, mainCounter, totalCounter, treelist,
- tanklist, arena, sizeTank, Googelon,
- buildingBoomThisFrameCounter, buildingBoomThisFrame);
- #endif
-
- if (!paused)
- doUpdate();
-
- #ifdef SOLARIS
- else /* sleep a while */
- {
- static struct timespec rqtp, rmtp;
- rqtp.tv_sec = 0;
- rqtp.tv_nsec = 500 * 1000000; /* 500 ms delay */
- nanosleep(&rqtp, &rmtp);
- }
- #endif
- #ifdef SGIVERSION
- else
- sleep(1);
- #endif
-
- /*************************************************/
- /* rotate the plane in demo mode omniscient view */
- /*************************************************/
-
- if ((view == OMNISCIENTVIEW) && (mode == DEMOMODE))
- {
- if (!paused)
- yrot += 10;
- xrot = 300;
- }
-
- /************************************************/
- /* find newest vehicle visible on the plane */
- /************************************************/
-
- lastTankY = NOTANKONPLANE;
- lastTankTheta = lastTankRad = 0;
-
- for(ttank = tanklist->next; (ttank != NULL) && (lastTankY <= NOTANKONPLANE); ttank = ttank->next)
- if ((fabs(ttank->x) <= PLANESIZE) && (fabs(ttank->z) <= PLANESIZE) && (ttank->damage > 0)
- && (ttank->rad < 10))
- {
- lastTankY = ttank->y + 0.4;
- lastTankTheta = ttank->theta + PI;
- lastTankRad = ttank->rad + 1.5;
- }
-
- /************************************************/
- /* ensure all monster variables are within range*/
- /************************************************/
-
- if (xrot > 600)
- xrot = 600;
-
- if (xrot < 0)
- xrot = 0;
-
- if (yrot < 0)
- yrot += 3600;
-
- if (yrot >= 3600)
- yrot -= 3600;
-
- if (Googelon.headHorzRotate < 0)
- Googelon.headHorzRotate += 3600;
-
- if (Googelon.headHorzRotate >= 3600)
- Googelon.headHorzRotate -= 3600;
-
- if (Googelon.headVertRotate < -400)
- Googelon.headVertRotate = -400;
-
- if (Googelon.headVertRotate > 400)
- Googelon.headVertRotate = 400;
-
- if (targets->next != NULL)
- {
- for(temptarget = targets->next; temptarget != NULL; temptarget = temptarget->next)
- {
- if (temptarget->monster.headHorzRotate < 0)
- temptarget->monster.headHorzRotate += 3600;
-
- if (temptarget->monster.headHorzRotate >= 3600)
- temptarget->monster.headHorzRotate -= 3600;
-
- if (temptarget->monster.headVertRotate < -400)
- temptarget->monster.headVertRotate = -400;
-
- if (temptarget->monster.headVertRotate > 400)
- temptarget->monster.headVertRotate = 400;
- }
- }
-
- /************************************************/
- /* draw everything */
- /************************************************/
-
- doDisplay();
-
- /***************************************************/
- /* limit the game to about 20fps for fast machines */
- /***************************************************/
-
- #if defined SGIVERSION || defined SOLARIS
- gettimeofday(&endTime, NULL);
-
- while (((endTime.tv_sec - startTime.tv_sec) * 1000 +
- (endTime.tv_usec - startTime.tv_usec) * 0.001) < 45)
- {
- #ifdef SGIVERSION
- sginap(1);
- # endif
- # ifdef SOLARIS
- static struct timespec rqtp, rmtp;
-
- rqtp.tv_sec = 0;
- rqtp.tv_nsec = 2 * 1000000; /* 2 ms delay */
- nanosleep(&rqtp, &rmtp);
- # endif
- gettimeofday(&endTime, NULL);
- }
- #endif
-
- /*
- #ifdef MACVERSION
-
- macEnd = tkNow();
- this works on 68K macs but the time never changes on a PPC (sigh)
- while((macEnd - macStart) < 45000)
- {
- macEnd = tkNow();
- }
-
- macStart = macEnd;
-
- #endif
- */
-
- #ifdef AMIGA
- #ifdef __PPC__
- GetSysTimePPC(&endTime);
- #else
- #error "No M68k support"
- #endif
- while (((endTime.tv_secs - startTime.tv_secs) * 1000 +
- (endTime.tv_micro - startTime.tv_micro) * 0.001) < 45)
- {
- Delay(1);
- #ifdef __PPC__
- GetSysTimePPC(&endTime);
- #else
- #error "No M68k support"
- #endif
- }
- #endif
-
- startTime = endTime;
- }
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* showCommands */
- /* */
- /* print out the list of command line arguments */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- #ifndef MACVERSION
-
- void showCommands(char * progName)
- {
- fprintf (stderr, "\n\n");
-
- #ifdef SOLARIS
- fprintf (stderr, "Usage: %s [-a] [-b] [-d level] [-m] [-s] [-help]\n", progName);
- #else
- fprintf (stderr, "Usage: %s [-a] [-b] [-d level] [-m] [-s] [-c] [-h #] [-n] [-p #] [-help]\n", progName);
- #endif
-
- fprintf (stderr, " -a)lone fight alone\n");
- fprintf (stderr, " -b)ackdrop hide the overlays\n");
- fprintf (stderr, " -d)etail n set level-of-detail from 0 (low) to 2 (high)\n");
- fprintf (stderr, " -m)usic initially turn on the music\n");
- fprintf (stderr, " -s)ound initially turn on the sound effects\n");
- fprintf (stderr, " -help show this list of command line options\n\n");
-
- #ifdef SOLARIS
- fprintf (stderr, "Multiplayer options not yet supported:\n");
- #else
- fprintf (stderr, " Multiplayer options:\n");
- #endif
-
- fprintf (stderr, " -c)lient declare yourself as a client in a net game\n");
- fprintf (stderr, " -h)ost # give the address of the host in a net game\n");
- fprintf (stderr, " -n)etwork declare yourself as a server in a net game\n");
- fprintf (stderr, " -p)ort # declare the port # being used in a net game\n");
-
- #ifdef MESA_TK_VERSION
- tkQuit();
- #else
- exit(1);
- #endif
- }
-
- #endif
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* checkArguments */
- /* */
- /* change game settings based on the command line arguments */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- #ifndef MACVERSION
-
- void checkArguments(int argc, char* argv[])
- {
- register int argument;
- int port;
- char portName[40];
-
- for (argument=1;argument < argc;argument++)
- {
- if (((strcmp(argv[argument], "-sound") == 0) ||
- (strcmp(argv[argument], "-s") == 0) )&& !noSound)
- turnSoundOn();
-
- else if (((strcmp(argv[argument], "-music") == 0) ||
- (strcmp(argv[argument], "-m") == 0)) && !noSound)
- turnMusicOn();
-
- else if ((strcmp(argv[argument], "-alone") == 0) ||
- (strcmp(argv[argument], "-a") == 0))
- alone = 1;
-
- else if ((strcmp(argv[argument], "-detail") == 0) ||
- (strcmp(argv[argument], "-d") == 0))
- {
- if ((argument + 1) < argc)
- {
- lod = atoi(argv[argument + 1]);
- if (lod < 0 || lod > 2)
- showCommands(argv[0]);
- argument++;
- }
- else
- showCommands(argv[0]);
- }
-
- else if ((strcmp(argv[argument], "-network") == 0) ||
- (strcmp(argv[argument], "-net") == 0) ||
- (strcmp(argv[argument], "-n") == 0))
- netUp = 1;
-
- else if ((strcmp(argv[argument], "-backdrop") == 0) ||
- (strcmp(argv[argument], "-b") == 0))
- backdrop = 1;
-
- else if ((strcmp(argv[argument], "-client") == 0) ||
- (strcmp(argv[argument], "-c") == 0))
- client = 1;
-
- else if ((strcmp(argv[argument], "-host") == 0) ||
- (strcmp(argv[argument], "-h") == 0))
- {
- if ((argument+1) < argc)
- {
- setHostAddr(argv[argument+1]);
- argument++;
- }
- else
- showCommands(argv[0]);
- }
- else if ((strcmp(argv[argument], "-port") == 0) ||
- (strcmp(argv[argument], "-p") == 0))
- {
- if ((argument+1) < argc)
- {
- strcpy(portName, argv[argument+1]);
- sscanf(portName, "%d", &port);
- setPortNumber(port);
- argument++;
- }
- else
- showCommands(argv[0]);
- }
-
- else if ((strcmp(argv[argument], "-help") == 0))
- {
- showCommands(argv[0]);
- }
- else
- {
- showCommands(argv[0]);
- }
- }
- }
-
- #endif
-
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /* main */
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
- /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
-
- main (int argc, char*argv[])
- {
- #if defined SGIVERSION || defined SOLARIS
-
- gettimeofday(&startTime, NULL);
-
- #endif
-
- /*
- #ifdef MACVERSION
-
- macStart = tkNow();
-
- #endif
- */
-
- #ifdef AMIGAVERSION
- #ifdef __PPC__
- GetSysTimePPC(&startTime);
- #else
- #error "No M68k support"
- #endif
- #endif
-
- /******************/
- /* initialization */
- /******************/
-
- frames = 0;
- initialization();
-
- /********************************/
- /* check command line arguments */
- /********************************/
-
- #ifndef MACVERSION
-
- checkArguments(argc, argv);
-
- #endif
-
- /**********************************************/
- /* set starting conditions for chosen monster */
- /* (here so network options are used */
- /**********************************************/
-
- setPlayConditions();
-
-
- /******************/
- /* set up network */
- /******************/
-
- #ifndef MACVERSION
- if ((netUp == 1) && (client == 1))
- {
- showError("must be either a host or a client, not both");
- exit(1);
- }
-
- if (netUp)
- {
- netUp = setUpNetwork();
- }
-
- if (client)
- {
- client = setUpClient();
- }
- #endif
-
-
- /****************/
- /* set it going */
- /****************/
-
- tkExec();
-
- return 0;
-
- }
-